在Golang中将一个指针从一种类型转换为另一种类型时出现错误。

huangapple go评论179阅读模式
英文:

Casting from one pointer to pointer type to another in Golang error

问题

有人能告诉我为什么这段代码无法编译吗?

package main

type myint int
func set(a **myint) {
    i := myint(5)
    *a = &i 
}

func main() {
    var k *int
    set((**myint)(&k)) // 无法将 &k (类型为 **int) 转换为类型 **myint
    print(*k)
}

到目前为止,我的推理是这样的。在Golang中,所有类型都是不同的,但只要底层类型相同,它允许使用类似C的强制类型转换语法从一种类型转换为另一种类型。在我的例子中,将'int'转换为'myint'不是问题。'*int'转换为'*myint'也不是问题。问题出现在指针到指针的转换上。我已经被困在这个问题上第二天了。任何帮助都将不胜感激。

英文:

Can anyone tell my why this wouldn't compile?

package main

type myint int
func set(a **myint) {
	i := myint(5)
	*a = &i 
}

func main() {
	var k *int
	set( (**myint)(&k) ) // cannot convert &k (type **int) to type **myint
	print( *k )
}

My reasoning so far is this. All types in Golang are different, but it allows to convert from one type to another with C-like cast syntax as long as underlying types are identical. In my example, converting 'int' to 'myint' is not a problem. '*int' to '*myint' isn't either. It's when you have pointer to pointer problems arise. I've been stuck on this for the second day now. Any help is appreciated.

答案1

得分: 27

这是我的分析。

(**myint)(&k) -- 无法将 &k (type **int) 转换为 type **myint

type **inttype **myint 是未命名的指针类型,它们的指针基类型 type *inttype *myint 的底层类型不相同。

如果 T (*int*myint) 是指针类型的字面量,对应的底层类型就是 T 本身。

(*myint)(k) -- 可以将 k (type *int) 转换为 type *myint

type *inttype *myint 是未命名的指针类型,它们的指针基类型 type inttype myint (type myint int) 的底层类型相同。

如果 T (int) 是预声明的类型,对应的底层类型就是 T 本身。如果 T (myint) 既不是预声明的类型也不是类型字面量,T 的底层类型就是在其类型声明中 T 所引用的类型的底层类型 (type myint int)。

(myint)(*k) -- 可以将 *k (type int) 转换为 type myint

type inttype myint 的底层类型相同。

如果 T (int) 是预声明的类型,对应的底层类型就是 T 本身。如果 T (myint) 既不是预声明的类型也不是类型字面量,T 的底层类型就是在其类型声明中 T 所引用的类型的底层类型 (type myint int)。

这是从类型部分修改后的底层类型示例,使用整数和整数指针。

type T1 int
type T2 T1
type T3 *T1
type T4 T3

intT1T2 的底层类型都是 int*T1T3T4 的底层类型都是 *T1

参考资料:

Go 编程语言规范

类型转换

类型

类型和值的属性

类型声明

预声明的标识符

指针类型

英文:

Here's my analysis.

(**myint)(&k) -- cannot convert &k (type **int) to type **myint:

type **int and type **myint are unnamed pointer types and their pointer base types, type *int and type *myint, don't have identical underlying types.

If T (*int or *myint) is a pointer type literal, the corresponding underlying type is T itself.

(*myint)(k) -- can convert k (type *int) to type *myint:

type *int and type *myint are unnamed pointer types and their pointer base types, type int and type myint (type myint int), have identical underlying types.

If T (int) is a predeclared type, the corresponding underlying type is T itself. If T (myint) is neither a predeclared type or nor a type literal, T's underlying type is the underlying type of the type to which T refers in its type declaration (type myint int).

(myint)(*k) -- can convert *k (type int) to type myint:

type int and type myint have identical underlying types.

If T (int) is a predeclared type, the corresponding underlying type is T itself. If T (myint) is neither a predeclared type or nor a type literal, T's underlying type is the underlying type of the type to which T refers in its type declaration (type myint int).

Here's the underlying type example from the Types section revised to use integers and int pointers.

type T1 int
type T2 T1
type T3 *T1
type T4 T3

The underlying type of int, T1, and T2 is int. The underlying type of *T1, T3, and T4 is *T1.

References:

The Go Programming Language Specification

Conversions

Types

Properties of types and values

Type declarations

Predeclared identifiers

Pointer Type

答案2

得分: 15

这是您的程序的两个功能上等效的工作版本。

package main

type mypint *int

func set(a *mypint) {
	i := int(5)
	*a = &i
}

func main() {
	var k *int
	set((*mypint)(&k))
	print(*k)
}

http://play.golang.org/p/l_b9LBElie

package main

type myint int

func set(a *myint) *myint {
	i := myint(5)
	a = &i
	return a
}

func main() {
	var k *int
	k = (*int)(set((*myint)(k)))
	print(*k)
}

http://play.golang.org/p/hyaPFUNlp8

英文:

Here are two functionally equivalent working versions of your program.

package main

type mypint *int

func set(a *mypint) {
	i := int(5)
	*a = &i
}

func main() {
	var k *int
	set((*mypint)(&k))
	print(*k)
}

http://play.golang.org/p/l_b9LBElie

package main

type myint int

func set(a *myint) *myint {
	i := myint(5)
	a = &i
	return a
}

func main() {
	var k *int
	k = (*int)(set((*myint)(k)))
	print(*k)
}

http://play.golang.org/p/hyaPFUNlp8

huangapple
  • 本文由 发表于 2011年3月20日 18:43:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/5367961.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定