类型断言是否会改变go中的值?

时间:2018-03-20 21:32:44

标签: go interface

在这里新手。

我有一张地图,其中关键参数应为[]string

但是,如果我尝试直接使用该值arguments := m["arguments"],它似乎不是正确的类型。如果稍后使用arguments...追加到另一个切片,我会获得Cannot use 'arguments' (type interface{}) as type []string

我通过将作业分配到类型检查arguments, _ := m["arguments"].([]string)来修复此问题。这有效,但我不知道为什么。 type assertion也在进行转换吗?

完整示例如下:

import (
    "github.com/fatih/structs"
    "strings"
)

var playbookKeyDict = map[string]string{
    "Playbook": "",
    "Limit" : "--limit",
    "ExtraVars" : "--extra-vars",
}

type Playbook struct {
    Playbook string `json:"playbook" xml:"playbook" form:"playbook" query:"playbook"`
    Limit string `json:"limit" xml:"limit" form:"limit" query:"limit"`
    ExtraVars string `json:"extra-vars" xml:"extra-vars" form:"extra-vars" query:"extra-vars"`
    Arguments []string `json:"arguments" xml:"arguments" form:"arguments" query:"arguments"`
    Args []string
}

func (p *Playbook) formatArgs() {
    // is it worth iterating through directly with reflection instead of using structs import?
    // https://stackoverflow.com/questions/21246642/iterate-over-string-fields-in-struct
    m := structs.Map(p)

    // direct assignment has the wrong type?
    // arguments := m["arguments"]
    arguments, _ := m["arguments"].([]string)
    delete(m, "arguments")

    for k, v := range m {
        // Ignore non-strings and empty strings
        if val, ok := v.(string); ok && val != "" {
            key := playbookKeyDict[k]
            if key == "" {
                p.Args = append(p.Args, val)
            } else {
                p.Args = append(p.Args, playbookKeyDict[k], val)
            }
        }
    }
    p.Args = append(p.Args, arguments...)
}

1 个答案:

答案 0 :(得分:4)

类型断言用于获取使用接口包裹的值。

m := structs.Map(p)

Map(v interface{}){}

在所述情况下,Map函数实际上将接口作为其参数。它包装了[]string的类型及其作为切片的基础值。可以使用Relection reflect.TypeOf()来检查该类型。

func TypeOf(i interface{}) Type

据Russ Cox博客Interfaces

  

接口值表示为给出指针的双字对   有关存储在接口中的类型和指向的信息   相关数据。

Golang规范

中所述
  

对于接口类型的表达式x和类型T,表示主要的   表达

x.(T)
     

断言x不是nil,并且存储在x中的值是T类型。   符号x。(T)称为类型断言。

对于错误部分: -

Cannot use 'arguments' (type interface{}) as type []string

我们首先需要使用类型断言从接口获取类型[]string的基础值。