go - 类型断言会改变go中的值吗?

标签 go interface

这里是新手。

我有一张 map ,其中关键参数应该是 []string

但是,如果我尝试直接使用该值 arguments := m["arguments"] 它似乎不是正确的类型。当稍后使用 arguments... 附加到另一个 slice 时,我得到 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...)
}

最佳答案

类型断言用于获取使用接口(interface)包装的值。

m := structs.Map(p)

Map(v interface{}){}

Map 函数实际上是以接口(interface)作为参数的。它包装了 []string 类型及其底层值 slice。可以使用 Relection 检查类型reflect.TypeOf()

func TypeOf(i interface{}) Type

根据 Russ Cox 博客 Interfaces

Interface values are represented as a two-word pair giving a pointer to information about the type stored in the interface and a pointer to the associated data.

Golang 中所述规范

For an expression x of interface type and a type T, the primary expression

x.(T)

asserts that x is not nil and that the value stored in x is of type T. The notation x.(T) is called a type assertion.

对于错误部分:-

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

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

关于go - 类型断言会改变go中的值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49394466/

相关文章:

go - 如何让多个 goroutine 等待另一个 goroutine 的输出

unit-testing - 忽略 Golang 测试覆盖率计算中的代码块

Java多线程编程

if-statement - Java8将长接口(interface)方法拆分为单独的方法

go - 有没有办法在golang中计算类型的大小?

oop - 如何实现功能共享相同逻辑的接口(interface)?

go - 在 Golang 中将接口(interface){}转换为结构

c# - 在 C# 中实现接口(interface)的通用方法时出现奇怪的错误。这里到底出了什么问题?

c# - 没有返回类型协变的接口(interface)继承

java - 为整个服务中使用的数据对象设计通用接口(interface)