方法 – golang在T和* T上区分方法集的原因是什么?

前端之家收集整理的这篇文章主要介绍了方法 – golang在T和* T上区分方法集的原因是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在学习的过程中,这让我感到困惑.我们都知道T上的方法只会影响T的副本,* T上的方法会影响T上的实际数据.

为什么T上的方法也可以被* T使用,但是不允许使用相反的方法?那么,你能给我一个例子(或理由)说明为什么他们不允许T使用* T的方法

这个设计的优点和缺点是什么?

这里有很多答案,但没有人回答为什么会这样.

首先让我们假设你有一个* T并且想要调用一个采用T的方法.为此,你需要做的就是将* yourT(其中*用于取消引用指针)传递给函数.这是可能的,因为您只是在已知位置复制内存块.

现在让我们说你有一个T并想要一个* T.你可能会认为你可以做& yourT并得到它的地址.但生活并非总是如此简单.并不总是有一个静态地址.

the spec开始:

For an operand x of type T,the address operation &x generates a pointer of type *T to x. The operand must be addressable,that is,either a variable,pointer indirection,or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement,x may also be a (possibly parenthesized) composite literal.

您可能会问自己为什么会将这些任意限制放在获取内存地址上.每个变量都必须有一些内存地址,对吧?虽然这是事实,但优化可以使这些地址相当短暂.

例如,假设变量位于地图内:

res := TMap["key"].pointerMethod()

在这种情况下,你实际上是在说你想要一个指向内存的指针.这将迫使Go的每个实现以这样的方式实现map,即内存地址保持静态.这将严重限制运行时的内部结构,并使实施者在构建有效映射时更少自由.

还有其他示例,如函数返回或接口,但您只需要一个示例来证明无法保证操作.

最重要的是,计算机内存并不简单,虽然你可能想说“只是拿地址”,但并不总是这么简单.取一个保证是静态的地址并不总是可行的.因此,您无法保证T的任何实例都可以转换为指针并传递给指针方法.

猜你在找的Go相关文章