为了账号安全,请及时绑定邮箱和手机立即绑定

为什么不允许在类型断言之后直接为结构的字段赋值

为什么不允许在类型断言之后直接为结构的字段赋值

Go
交互式爱情 2022-08-01 18:36:27
这是结构。它实现(使用BiOperators作为方法接收器)。这些只是一些用于测试的代码,我在这里省略了它。BiOperatorsMyInterface1type BiOperators struct {    oprt1 float64    oprt2 float64}我的问题是为什么我不能在类型断言后将值分配给oprt1func testTypeAssertion() {    bio := BiOperators{111, 222}    arr := []MyInterface1{bio, &bio}    // I can do the conversion and output field oprt2    fmt.Println((arr[0].(BiOperators)).oprt2)    // But when I want to directly assign value to it, I got the following error    // cannot assign to arr[0].(BiOperators).oprt2go    // (arr[0].(BiOperators)).oprt2 = 99 <----this line is error    // and I can't create a pointer to do the assignment    // the following line has error : cannot take the address of arr[0].(BiOperators)go    // bioCvt2 := &(arr[0].(BiOperators)) <----this line is error too    // I can using the following lines to do the assignment. But it will create a new struct    bioCvt := (arr[0].(BiOperators))    bioCvt.oprt2 = 333    fmt.Println("bioCvt", bioCvt)    fmt.Println("arr[0](assigned using bio)", arr[0])}那么,是否无论如何都要不要在类型断言之后创建新的结构来执行字段分配?
查看完整描述

1 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

当您放入接口数组时,将创建一个副本并存储在第零个元素中。第一个元素包含一个指向的指针,因此不会为该元素创建任何副本。同样,当您从接口转换回结构类型时,将创建该值的另一个副本。据推测,编译器或语言不允许这样做,因为您将修改无法再次访问的副本以以任何方式使用该值。biobiobio


即使使用上面的代码,类似的情况仍然会发生。修改 on 上的字段时,它根本不会修改,因为您正在修改副本。bioCvtbio


但是,如果将第一个元素转换为指针,则可以对其进行修改,这是 中的基础值:bio


func testTypeAssertion() {

    bio := BiOperators{111, 222}


    arr := []MyInterface1{bio, &bio}


    (arr[1].(*BiOperators)).oprt2 = 99 // does not error anymore


    fmt.Println("arr[1](assigned using bio)", arr[1])

    fmt.Println("bio", bio) // This will print 99

}


查看完整回答
反对 回复 2022-08-01
  • 1 回答
  • 0 关注
  • 87 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信