【问题标题】:Why is it illegal to assign pointer to pointer for type definitions involving pointers?为什么为涉及指针的类型定义分配指向指针的指针是非法的?
【发布时间】:2018-07-05 18:11:29
【问题描述】:

我有以下代码:

package main

type Vertex struct {
    X, Y float64
}

type VertexPointer *Vertex

func main() {
    v := Vertex{3, 4}
    v_ptr := &v

    var test_1 *Vertex = &v
    var test_2 **Vertex = &v_ptr

    var test_3 VertexPointer = &v
    var test_4 *VertexPointer = &v_ptr
}

当我尝试运行它时(我使用的是 Go 1.6.2)我收到以下错误:

# command-line-arguments
./pointers.go:17: cannot use &v_ptr (type **Vertex) as type *VertexPointer in assignment

我很困惑为什么涉及 test_3 的作业有效,而不是 test_4。根据我一直在阅读的内容,我的理解是两个作业都应该起作用,或者它们都不应该起作用。描述的行为是不是有点不一致?

【问题讨论】:

  • 您的问题中没有任何类型别名。
  • 类型别名是type A = B 而不是type A B
  • @leaf 那我怎么称呼type A B?我想使用 typedef,但似乎 Go 语言中没有使用该术语。
  • 称为类型定义。你可以阅读 golang 规范。

标签: pointers go


【解决方案1】:

这一切都由Spec: Assignability“管理”。分配给 test_3 的内容如下:

x 可分配给T 类型的variable(“x 可分配给T”)在任何这些情况下:

并且任何可分配性规则都没有涵盖test_4,因此是不允许的。

底层类型详见Spec: Types:

每个类型T 都有一个基础类型:如果T 是预先声明的布尔、数字或字符串类型之一,或者是类型文字,则相应的基础类型是T本身。否则,T 的基础类型是T 在其type declaration 中引用的类型的基础类型。

如果是test_3

var test_3 VertexPointer = &v

test_3 的类型是 VertexPointer(明确指定),&v 的类型是 *Vertex。两者的底层类型都是*Vertex,而&v(即*Vertex)的类型是一个未命名的类型,所以赋值是OK的。 Vertex 是命名类型,但派生类型如 *Vertex[]Vertex 是未命名类型。

如果是test_4

var test_4 *VertexPointer = &v_ptr

test_4 的类型是 *VertexPointer&v_ptr 的类型是 **Vertex,因为 v_ptr 的类型是 *Vertex,而不是 VertexPointertest_4的底层类型是*VertexPoitner&v_ptr的底层类型是**Vertex。基础类型不匹配。所以没有适用的可分配性规则,所以这个分配是好的。

查看类似问题:Custom type passed to function as a parameter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2011-01-14
    • 2023-04-07
    • 2011-12-29
    • 2018-05-16
    • 2011-12-16
    • 1970-01-01
    相关资源
    最近更新 更多