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

2023-11-21

这是我学习go过程中最困惑的地方。我们都知道方法T只影响副本T,以及方法*T会影响实际数据T.

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

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


这里有很多答案,但没有一个回答为什么会出现这种情况。

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

现在假设您有一个 T 并且想要一个 *T。您可能认为只需执行 &yourT 即可获取其地址。但生活并不总是那么简单。并不总是有静态地址可供使用。


From the spec:

对于 T 类型的操作数 x,地址运算 &x 生成一个指向 x 的 *T 类型的指针。操作数必须是可寻址的,即变量、指针间接或切片索引操作;或可寻址结构操作数的字段选择器;或可寻址数组的数组索引操作。作为可寻址性要求的一个例外,x 也可以是(可能带括号的)复合文字。

您可能会问自己为什么他们会对获取内存地址施加这些任意限制。每个变量必须有some内存地址,对吗?虽然这是事实,但优化可能会使这些地址变得相当短暂。

例如,假设变量位于映射内:

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

在这种情况下,您实际上是在说您希望将指向内存的指针保存在映射内。这将迫使 Go 的每个实现都以内存地址保持静态的方式实现映射。这将严重限制运行时的内部结构,并使实现者在构建高效映射时的自由度大大降低。

还有其他示例,例如函数返回或接口,但您只需要一个示例即可证明该操作不保证可行。


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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

golang 区分 T 和 *T 上的方法集的原因是什么? 的相关文章

  • 初始化嵌套匿名结构

    我有一个 json 作为 fields time id status customerId additionalDetail pageInfo start 0 rows 1000 我想将我的结构编组到上面的 json 并创建如下结构 typ
  • 需要帮助在 JavaScript 中过滤数组

    这是我在 JavaScript 中的数组 let myArray Bob Katy Bob Bob Katy 我想通过检查来过滤这个数组如果当前值等于其后或之前的值 我不太确定如何实现这一目标 但是 有人能给我指出一个方向吗 现在我知道如何
  • 是否可以获取有关 Golang 中调用者函数的信息?

    是否可以获取有关 Golang 中调用者函数的信息 例如 如果我有 func foo Do something func main foo 我怎样才能得到那个foo已被呼叫来自main 我可以用其他语言实现这一点 例如在 C 中我只需要使用
  • 如何在运行“go test”时排除或跳过特定目录[重复]

    这个问题在这里已经有答案了 go test go list grep v vendor coverprofile testCoverage txt 我正在使用上述命令来测试文件 但有 1 个名为 Store 的文件夹我想从测试中排除 怎样才
  • 如何将UTC时间转换为unix时间戳

    我正在寻找将 UTC 时间字符串转换为 unix 时间戳的选项 我的字符串变量是02 28 2016 10 03 46 PM并且需要将其转换为 unix 时间戳 例如1456693426 知道该怎么做吗 首先 unix时间戳14566934
  • 获取块参数个数

    我需要获取给定块所采用的参数数量 例如 foobar 1 2 3 a b c def foobar x y z block need to obtain number of arguments in block which would be
  • 使用 HTTPS GRC 从 AWS Codecommit 获取私有存储库

    我正在尝试导入位于 AWS codecommit 中的模块 为了克隆存储库 我使用 HTTPS GRC Git 远程代码提交 方法 该方法使用 Google Suite 凭证来访问 AWS 控制台 我用来克隆存储库的命令是 git clon
  • 如何使用 javascript 更改文件扩展名

    有谁知道在 Javascript 中更改文件扩展名的简单方法吗 例如 我有一个带有 first docx 的变量 但我需要将其更改为 first html 这将改变字符串包含文件名 let file first docx file file
  • GOMAXPROCS 默认值是多少?

    不设置同名环境变量时是否保证GOMAXPROCS设置为1 此代码显示的值 package main import runtime fmt func getGOMAXPROCS int return runtime GOMAXPROCS 0
  • 时间:2019-03-17 标签:c#backgroundworker和partialclass

    我在实现从堆栈溢出获得的代码时遇到问题 它是关于终止后台工作进程的 我的代码如下 using System using System Collections Generic using System Data using System Dr
  • 正确的文件扩展名或缩写是什么。 golang 的文本/模板?

    我正在考虑为其创建语法荧光笔 但我不知道这种特定类型模板的常规缩写 In 例子之一 http golang org pkg text template example Template helpers从文本 模板 godoc 中 它们引用
  • 无法从 C# WPF 中的另一个窗口调用方法

    好吧 假设我有两个窗户 在第一个中我有一个方法 public void Test Label Content works 在第二个方法中 我称此方法为 MainWindow mw new MainWindow mw Test 但什么也没发生
  • 如何使信号量超时

    Go 中的信号量是通过通道来实现的 一个例子是这样的 https sites google com site gopatterns concurrency semaphores https sites google com site gop
  • “go.tools”的权限被拒绝错误

    当我尝试安装 go 工具时 我的权限被拒绝 usr local go pkg tool linux amd64 cover 我可以接受 因为它是 usr local 目录及需求root使用权 但我的第一个疑问是为什么当我设置时它试图安装在这
  • Golang 正则表达式在字符串之间替换

    我有一些可能采用以下形式的字符串 MYSTRING MYSTRING n MYSTRING n MYSTRING randomstringwithvariablelength n 我希望能够将其正则表达式为MYSTRING foo 基本上替
  • `as.matrix` 和 `as.data.frame` S3 方法与 S4 方法

    我注意到定义as matrix or as data frame作为 S4 类的 S3 方法 使例如lm formula objS4 and prcomp object 开箱即用 如果它们被定义为 S4 方法 则这不起作用 为什么将方法定义
  • 在 Go 中,如何将结构体转换为字节数组?

    我有一个我定义的结构实例 我想将其转换为字节数组 我尝试了 byte my struct 但这不起作用 另外 我还被指出二进制包 http golang org pkg encoding binary 但我不确定我应该使用哪个函数以及应该如
  • select 语句是否保证通道选择的顺序?

    继从这个答案 https stackoverflow com a 25795236 274460 如果一个 goroutine 在两个通道上进行选择 是否保证通道的选择顺序与其发送的顺序相同 我对发送者是单线程的情况特别感兴趣 例如 是否保
  • 如何使用 GOPATH 的 Samba 服务器位置?

    我正在尝试将 GOPATH 设置为共享网络文件夹 当我进入 export GOPATH smb path to shared folder I get go GOPATH entry is relative must be absolute
  • 如何将接口转换为接口切片?

    我的输入是interface 而且我知道它可以是任何类型的数组 我想读取我输入的元素之一 所以我尝试将我的interface 进入一个 interface 但是 go 会给我以下错误 恐慌 接口转换 interface 是 map stri

随机推荐

  • 如何从字符串名称渲染反应组件

    我想从它的字符串名称动态渲染一个反应组件 这是我所做的 但它不起作用 这可以做到吗 一个例子确实会有帮助 string name 是组件的名称 var MyComponent React createElement window strin
  • 带有 SWT.Browser 和 XULRunner 的 RCP

    我正在使用 SWT Browser 开发 RCP 应用程序 Windows SWT MOZILLA Browser browser new Browser parent SWT MOZILLA 它与旧的 XULRunner 3 6 23 和
  • 如何在CSS中按百分比定义不透明度?

    是否可以在 CSS 中按百分比 例如 30 定义 CSS 的不透明度 似乎不起作用 现在我只能按小数点进行 https css tricks com almanac properties o opacity test opacity 0 3
  • 对 std::basic_string 的未定义引用

    我正在编译我的项目并看到链接问题 g Wl z now Wl z relro pthread Wl z noexecstack fPIC Wl threads Wl thread count 4 B third party gold L W
  • log4net - FileAppender 在文件开头写入新条目

    是否可以在 log4net 中配置 FileAppender 以在日志文件的开头添加新条目 目前 它正在末尾添加条目 并且读取最新条目需要向下滚动整个日志 从头开始读会更舒服 我不知道该选项在 log4net 中是否可用 我不这么认为 但即
  • 为什么WPF中TextBox边框颜色坚持不改变?

    据我了解 我应该使用样式触发器来更新文本框聚焦时的边框颜色 然而 无论我做什么 它总是变成系统默认的蓝色 而不是我指定的黑色 有人有主意吗 代码如下
  • Objective-C/Cocoa:如何接受错误的服务器证书?

    Using NSURL请求 我正在尝试访问证书已过期的网站 当我发送请求时 我的连接 didFailWithError使用以下信息调用委托方法 1203 NSURLErrorDomain bad server certificate 我的搜
  • Ruby 'Range.last' 不会给出最后一个值。为什么?

    在 ruby Range 对象中使用三点表示法时 我得到以下结果 0 5 each n p n 0 1 2 3 4 当我使用 最后 方法时 我得到 0 5 last gt 5 我本来期望 4 这是一个错误吗 或者我对 Range 对象的概念
  • 未找到 MSBuild 目标包

    我想打包我的 VS2010 Web 应用程序项目 准备使用 msdeploy 进行部署 在开发机器上我可以使用以下方法来做到这一点 MSBuild exe C path to WebApp csproj target package 但在我
  • WPF 可以在没有 DirectX 的情况下运行吗?

    这听起来可能是一个愚蠢的问题 但是 如果没有支持 DirectX Direct3D 的显卡 驱动程序 WPF 是否会停止运行 或者只是运行速度变慢 我知道 WPF 基于 DirectX Direct3D 即使是简单的控件 但我找不到有关该主
  • d3js 很好地过渡了带有添加点的线

    说我有一个path我创建了d3就像是 line d3 line curve d3 curveLinear x function d return x d x y function d return y d y data x 0 y 0 x
  • Next.js 设置背景图片

    我正在尝试向 next js 添加背景图像 但无法这样做 我尝试过很多解决方案 内联 scc 样式 jsx 和其他技术 无法直接写入样式 因为它会出错 Error Expected a template literal or String
  • javascript循环冻结浏览器并且在循环之前看不到变化

    我有一个简单的 javascript 循环 如下所示 function runCode sample span removeAttr style for var i 0 i lt 100000 i console log new Date
  • 检查日期是否在指定日期之后?

    我正在尝试对日期进行验证 该日期应该只接受当前和未来的日期 如果日期是较旧的日期 那么它应该显示 该日期早于当前日期 我也想允许当前日期 现在 当将当前日期指定为 gievnDate 时 它 总是显示 该日期早于当前日期 但我期望输出为 日
  • 这是 iOS 8 Bug(旋转方向问题)吗?

    自 iOS 8 以来 我的应用程序运行得很好 但我在测试该应用程序时发现了一个问题 仅当我以横向模式启动应用程序时 才会在 iPad 上发生这种情况 如果它以纵向启动 则一切正常 没有旋转问题 如果我旋转设备 模拟器或真实设备 视图将旋转出
  • 如何用StAX修改一个巨大的XML文件?

    我有一个巨大的 XML 2GB 我需要添加新元素并修改旧元素 例如 我有
  • 网站上文件的上次修改日期

    有没有办法获取网站上文件的上次修改日期 即 这是我在那里的一个示例文件 http www ymcadetroit org atf cf 7B2101903E A11A 4532 A64D 9D823368A605 7D Birmingham
  • 如何限制 Eval 中的文本字符串

    我有一个超链接 其导航属性设置如下 NavigateUrl 如何将字符串限制为 140 个字符 我已经尝试过这个 Eval My Text ToString Substring 0 140 但如果字符串长度小于 140 个字符 则会引发异常
  • 访问 SimpleXMLElement 对象的某些属性

    When I print r 变量引用的 SimpleXMLElement 对象 xmlObject 我看到以下结构 SimpleXMLElement Object attributes gt Array uri gt example re
  • golang 区分 T 和 *T 上的方法集的原因是什么?

    这是我学习go过程中最困惑的地方 我们都知道方法T只影响副本T 以及方法 T会影响实际数据T 为什么方法上T也可以使用 T 但不允许相反的情况 那么 你能给我一个例子 或原因 说明为什么他们不允许方法 T被使用T 这种设计的优点和缺点是什么