Go语言 示例化接口

svujldwt  于 2023-04-03  发布在  Go
关注(0)|答案(2)|浏览(121)

我是Go的新手,有一件事我不明白,为什么当我想单独示例化接口时会出现编译错误,但当我使用该接口的数组形式时,没有编译错误。

type Flag interface {
  fmt.Stringer
}

func TestCheckRequiredFlag(t *testing.T) {
    testdata := []struct {
        st []Flag
    }{
        {
            st: []Flag{//allowed
                &StringFlag{Name: ""},
            },
        },
    }

    st := struct {
        st Flag
    }{
        st: Flag{// is not allowed
            &StringFlag{Name: ""},
        },
    }
}

此复合文字分配具有给定值的新结构示例。

htrmnn0y

htrmnn0y1#

大括号{}用于切片、结构、数组和Map的文字值。它们不用于接口值。如果你想要一个接口类型的文字值,你必须使用()语法,这会调用“类型转换”。
例如:

x := MyInterface(&MyStruct{})

x的类型为MyInterface
要更正代码,请执行以下操作:

st := struct {
        st Flag
    }{
        st: Flag(
            &StringFlag{Name: ""},
        ),
    }

你也可以完全删除类型转换,因为Go语言允许直接赋值给接口值,而转换是隐式的。更明确地说,可赋值性规则是这样说的(为了清晰起见,编辑了):
如果T是一个接口类型并且x实现了T,则V类型的值x可以赋值给T类型的变量。
这段代码也可以工作:

st := struct {
        st Flag
    }{
        st: &StringFlag{Name: ""},
    }

请注意,在复合文字中,如切片,结构和Map,给定的值被认为是 * 分配 * 到其各自的索引,字段或键,就像它们是变量一样,因此可分配性规则适用。

ac1kyiln

ac1kyiln2#

接口是一个抽象类型,不能示例化。我们只能创建一个实现接口的具体类型,然后创建该具体类型的示例**。但当你使用Flag接口的数组形式时,实际上是创建了一个实现Flag接口的具体类型切片,这是可以接受的。

相关问题