Go语言:利用 TDD 逐步为一个字典应用创建完整的 CRUD API

寻技术 Go编程 2023年07月12日 120

前言

在数组这一章节中,我们学会了如何按顺序存储值。现在,我们再来看看如何通过存储值,并快速查找它们。
Maps 允许你以类似于字典的方式存储值。你可以将视为单词,将视为定义。
所以,难道还有比构建我们自己的字典更好的学习 map 的方式吗?
 

正文

首先编写测试

dictionary_test.go 中编写代码:

package main

import "testing"

func TestSearch(t *testing.T) {
    dictionary := map[string]string{"test": "this is just a test"}

    got := Search(dictionary, "test")
    want := "this is just a test"

    if got != want {
        t.Errorf("got '%s' want '%s' given, '%s'", got, want, "test")
    }
}
声明 map 的方式有点儿类似于数组。
不同之处是,它以 map 关键字开头,需要两种类型。第一个是键的类型,写在 [] 中。第二个是值的类型,跟在 [] 之后。
键的类型很特别,它只能是一个可比较的类型,因为如果不能判断两个键是否相等,我们就无法确保我们得到的是正确的值。可比类型在语言规范中有详细解释。
另一方面,值的类型可以是任意类型,它甚至可以是另一个 map。

尝试运行测试

运行 go test 后编译器会提示失败信息 ./dictionary_test.go:8:9: undefined: Search

 

编写最少量的代码让测试运行并检查输出

dictionary.go 中:

package main

func Search(dictionary map[string]string, word string) string {
    return ""
}
测试应该失败并显示明确的错误信息
dictionary_test.go:12: got '' want 'this is just a test' given, 'test'
 

编写足够的代码使测试通过

func Search(dictionary map[string]string, word string) string {
    return dictionary[word]
}

从 map 中获取值和数组相同,都是通过 map[key] 的方式。

 

重构

func TestSearch(t *testing.T) {
    dictionary := map[string]string{"test": "this is just a test"}

    got := Search(dictionary, "test")
    want := "this is just a test"

    assertStrings(t, got, want)
}

func assertStrings(t *testing.T, got, want string) {
    t.Helper()

    if got != want {
        t.Errorf("got '%s' want '%s'", got, want)
    }
}

创建一个 assertStrings 辅助函数并删除 given 的部分让实现更通用。

 

使用自定义的类型

我们可以通过为 map 创建新的类型并使用 Search 方法改进字典的使用。

dictionary_test.go 中:

func TestSearch(t *testing.T) {
    dictionary := Dictionary{"test": "this is just a test"}

    got := dictionary.Search("test")
    want := "this is just a test"

    assertStrings(t, got, want)
}
我们已经开始使用 Dictionary 类型了,但是我们还没有定义它。然后要在 Dictionary 实例上调用 Search 方法。
我们不需要更改 assertStrings
dictionary.go 中:
type Dictionary map[string]string

func (d Dictionary) Search(word string) string {
    return d[word]
}

在这里,我们创建了一个 Dictionary 类型,它是对 map 的简单封装。定义了自定义类型后,我们可以创建 Search 方法。

版权声明:除特别声明外,本站所有文章皆是本站原创,转载请以超链接形式注明出处!

关闭

用微信“扫一扫”