Maps

作者: bocsoft | 来源:发表于2018-11-30 10:29 被阅读0次

声明 map 的方式有点儿类似于数组。不同之处是,它以 map 关键字开头,需要两种类型。第一个是键的类型,写在 [] 中。第二个是值的类型,跟在 [] 之后。
键的类型很特别,它只能是一个可比较的类型,因为如果不能判断两个键是否相等,我们就无法确保我们得到的是正确的值。
另一方面,值的类型可以是任意类型,它甚至可以是另一个 map。

Error 类型可以使用 .Error() 方法转换为字符串。

Map 有一个有趣的特性,不使用指针传递你就可以修改它们。这是因为 map 是引用类型。这意味着它拥有对底层数据结构的引用,就像指针一样。它底层的数据结构是 hash table 或 hash map。
Map 作为引用类型是非常好的,因为无论 map 有多大,都只会有一个副本。
如果值已存在,map 不会抛出错误。相反,它们将继续并使用新提供的值覆盖该值。

引用类型

Map 有一个有趣的特性,不使用指针传递你就可以修改它们。这是因为 map 是引用类型。这意味着它拥有对底层数据结构的引用,就像指针一样。它底层的数据结构是 hash tablehash map,你可以在这里阅读有关 hash tables 的更多信息。

Map 作为引用类型是非常好的,因为无论 map 有多大,都只会有一个副本。

引用类型引入了 maps 可以是 nil 值。如果你尝试使用一个 nil 的 map,你会得到一个 nil 指针异常,这将导致程序终止运行。

由于 nil 指针异常,你永远不应该初始化一个空的 map 变量:

var m map[string]string

相反,你可以像我们上面那样初始化空 map,或使用 make 关键字创建 map:

dictionary =  map[string]string{}
// OR
dictionary =  make(map[string]string)

这两种方法都可以创建一个空的 hash map 并指向 dictionary。这确保永远不会获得 nil 指针异常

package main

const (
    //ErrNotFound means the definition could not be found for the given word
    ErrNotFound = DictionaryErr("could not find the word you were looking for")
    //ErrWordExists means you are trying to add a word that is already known
    ErrWordExists = DictionaryErr("cannot add word because it already exists")
    //ErrWordDoesNotExist occurs when trying to update a word not in the dictionary
    ErrWordDoesNotExist = DictionaryErr("cannot update word because it does not exist")
)

//自定义错误类型
type DictionaryErr string

func (e DictionaryErr) Error() string {
    return string(e)
}

//Dictionary store definitions to words
type Dictionary map[string]string

//Search find a word in the dictionary
func (d Dictionary) Search(word string) (string, error) {
    definition, ok := d[word]
    if !ok {
        return "", ErrNotFound
    }
    return definition, nil
}

// Add inserts a word and definition into the dictionary
func (d Dictionary) Add(word, definition string) error {
    _, err := d.Search(word)
    switch err {
    case ErrNotFound:
        d[word] = definition
    case nil:
        return ErrWordExists
    default:
        return err
    }
    return nil
}

//Update changes the definition of a given word
func (d Dictionary) Update(word, definition string) error {
    _, err := d.Search(word)
    switch err {
    case ErrNotFound:
        return ErrWordDoesNotExist
    case nil:
        d[word] = definition
    default:
        return err
    }
    return nil
}

// Delete removes a word from the dictionary
func (d Dictionary) Delete(word string) {
    delete(d, word)
}



package main

import (
    "testing"
)

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

    t.Run("known word", func(t *testing.T) {
        got, _ := dictionary.Search("test")
        want := "this is just a test"

        assertStrings(t, got, want)
    })

    t.Run("unknown word", func(t *testing.T) {
        _, got := dictionary.Search("unknown")

        assertError(t, got, ErrNotFound)
    })
}

func TestAdd(t *testing.T) {
    t.Run("new word", func(t *testing.T) {
        dictionary := Dictionary{}
        word := "test"
        definition := "this is just a test"

        err := dictionary.Add(word, definition)

        assertError(t, err, nil)
        assertDefinition(t, dictionary, word, definition)
    })

    t.Run("existing word", func(t *testing.T) {
        word := "test"
        definition := "this is just a test"
        dictionary := Dictionary{word: definition}
        err := dictionary.Add(word, "new test")

        assertError(t, err, ErrWordExists)
        assertDefinition(t, dictionary, word, definition)
    })
}

func TestUpdate(t *testing.T) {
    t.Run("existing word", func(t *testing.T) {
        word := "test"
        definition := "this is just a test"
        newDefinition := "new definition"
        dictionary := Dictionary{word: definition}
        err := dictionary.Update(word, newDefinition)

        assertError(t, err, nil)
        assertDefinition(t, dictionary, word, newDefinition)
    })

    t.Run("new word", func(t *testing.T) {
        word := "test"
        definition := "this is just a test"
        dictionary := Dictionary{}

        err := dictionary.Update(word, definition)
        assertError(t, err, ErrWordDoesNotExist)
    })
}

func TestDelete(t *testing.T) {
    word := "test"
    dictionary := Dictionary{word: "test definition"}

    dictionary.Delete(word)

    _, err := dictionary.Search(word)

    if err != ErrNotFound {
        t.Errorf("Expected '%s' to be deleted", word)
    }
}
func assertStrings(t *testing.T, got, want string) {
    t.Helper()

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

func assertError(t *testing.T, got, want error) {
    t.Helper()

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

func assertDefinition(t *testing.T, dictionary Dictionary, word, definition string) {
    t.Helper()

    got, err := dictionary.Search(word)
    if err != nil {
        t.Fatal("should find added word:", err)
    }
    if definition != got {
        t.Errorf("got '%s' want '%s'", got, definition)
    }
}

相关文章

  • 认知地图,思维导图和概念图

    概述:认知地图(Cognitive maps),概念图(concept maps)和思维导图(mind maps)...

  • 常用iOS URL Scheme附录

    Safari: http://maps: http://maps.google.comPhone: tel:...

  • googlemap输入经纬度找到国家城市具体位置

    https://maps.googleapis.com/maps/api/geocode/json?latlng=...

  • 4.5 导入 maps

    Deno支持 import maps[https://github.com/WICG/import-maps]. ...

  • iOS GoogleMap 路径规划 Directions

    谷歌给的api:https://maps.googleapis.com/maps/api/directions/j...

  • 7.2、Convolution NeuralNetwork算法实

    Feature Maps: 20个feature maps pooling layer:作为图像压缩,将图像信息缩...

  • maps

    本节学习目标 什么是map? 如何创建map? 给map添加元素 获取map中的元素 删除map中的元素 获取ma...

  • Maps

    声明 map 的方式有点儿类似于数组。不同之处是,它以 map 关键字开头,需要两种类型。第一个是键的类型,写在 ...

  • MAPS

    I miss the taste of a sweeter life 我怀念生活中甜蜜的味道 I miss the...

  • Maps

    就是莫名其妙的喜欢着这样的音乐,梦想着,循着某人的脚步,一路走着走着,然而现实中,我只能循着自己的脚步,徘徊前进,...

网友评论

      本文标题:Maps

      本文链接:https://www.haomeiwen.com/subject/femccqtx.html