【问题标题】:Type conversion to similar type类型转换为相似类型
【发布时间】:2019-02-07 02:02:38
【问题描述】:

我正在尝试重用代码(键/值)对来构建 ec2.Tag 和 autoscaling.Tag 类型,它们也是键/值对。但我认为我对转换/铸造了解不够,请指教。提前谢谢你。

panic: 接口转换:interface {} is []struct { Key string;值字符串 },而不是 []*ec2.Tag

func (c *CloudWorks) GetTagCollection() interface{} {

    return []struct {
        Key   string
        Value string
    }{
     {
        Key:   "key-a",
        Value: "value-a",
    },
    {
        Key:   "key-b",
        Value: "value-b",
    },
    {
        Key:   "key-c",
        Value: "value-c",
    },
    }

}

func (c *CloudWorks) GetTags() []*ec2.Tag {

    //return []*autoscaling.Tag{

    // WORKS
    //return []*ec2.Tag{
    //  {
    //      Key:   aws.String("key1"),
    //      Value: aws.String("value1"),
    //  },
    //  {
    //      Key:   aws.String("key2"),
    //      Value: aws.String("value3"),
    //  },
    //  {
    //      Key:   aws.String("key3"),
    //      Value: aws.String("value3"),
    //  },
    //}

    // FAIL
    return c.GetTagCollection().([]*ec2.Tag)

}

编辑 我的目标是避免代码重复,如何在这两个函数中重复使用键值对,非常感谢。

func (c *CloudWorks) GetEC2Tags() []*ec2.Tag {

return []*ec2.Tag{
    {
        Key:   aws.String("key1"),
        Value: aws.String("value1"),
    },
    {
        Key:   aws.String("key2"),
        Value: aws.String("value3"),
    },
}

}

func (c *CloudWorks) GetAutoscalingTags() []*autoscaling.Tag {

return []*autoscaling.Tag{
    {
        Key:   aws.String("key1"),
        Value: aws.String("value1"),
    },
    {
        Key:   aws.String("key2"),
        Value: aws.String("value3"),
    },
}

}

【问题讨论】:

    标签: go aws-lambda aws-sdk


    【解决方案1】:

    您使用的术语不是conversion/casting,它是类型断言,用于获取接口的底层值。由于您在返回数据时用于包装函数内容的接口是一个结构切片。这就是错误背后的原因:

    panic: 接口转换:interface{} is []struct { Key string; 值字符串 },而不是 []*ec2.Tag

    类型断言是错误的,因为您使用的是[]*ec2.Tag 广告类型,它应该是从函数c.GetTagCollection() 返回的结构[]struct 的切片。因此,您应该将该类型的 assert 键入为:

    result := c.GetTagCollection().([]struct)
    

    在特殊形式的赋值或初始化中使用的类型断言,以便您检查类型断言是否有效:

    v, ok = x.(T)
    v, ok := x.(T)
    

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

    x.(T)
    

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

    更准确地说,如果 T 不是接口类型,x.(T) 断言 x 的动态类型与类型 T 相同。在这种情况下,T 必须 实现 x 的(接口)类型;否则类型断言是 无效,因为 x 不可能存储 T 类型的值。如果 T 是一个接口类型,x.(T) 断言 x 的动态类型 实现接口 T。

    注意:如果类型断言成立,则表达式的值是存储在 x 中的值,其类型为 T。如果类型断言为 false,则会发生运行时恐慌。

    编辑:Golang 对类型很严格。因此,在将值转换为另一种类型之前,您不能将一种类型的值分配给另一种类型。 AWS 使用提供的字符串创建自己的类型。举个例子:

    package main
    
    import (
        "fmt"
    )
    
    type MyInt int 
    
    func main() {
        var x int
        x = 1
        var y MyInt
        y = 1
        fmt.Println(x==y)
    }
    

    以上代码会抛出类型不匹配的错误

    prog.go:14:18:无效操作:x == y(不匹配的类型 int 和 MyInt)

    Playground 上的工作代码

    【讨论】:

    • return c.GetTagCollection().([]struct) 错误作为不兼容的类型。本质上,我试图将 tagCollection 重新用作接受键/值对的 []*ec2.Tag 和 []*autoscaling.Tag。现在我有两个重复的代码。还在努力学习,希望有解决办法?!
    • @user1619524 以GetTagCollection 函数的返回类型为例。
    • 请参阅编辑,我试图重新表述问题,谢谢。
    • @user1619524 你不能对不同的类型使用相同的变量。它不是重复的。机器人代码正在处理不同的类型。检查编辑的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    • 2014-04-29
    相关资源
    最近更新 更多