猿问

什么时候指针是惯用的?

我来自没有明确指针的语言,所以我真的不明白它们存在的意义(没有双关语)。

问题是,大多数时候我不知道为什么要传递指向函数的指针。我确实明白,当你传入一个指针时,对变量的修改是对所有地方的值进行的,但有什么意义呢?为什么不直接修改值并返回结果呢?

例如,http.HandlerFunc是一个接收http.ResponseWriter*http.Request作为参数的函数。我已经读过接口实际上是指针(对吗?),但我没有得到的是,为什么?

为什么我得到一个指向作者的指针?我没有修改它,我只是写信给它。而且,为什么我会得到一个指向请求的指针?我正在做类似的事情request.FormValue()

通过这些例子,我在这里试图确定的是“我什么时候需要传入一个指针?”这个问题的答案。

我现在这样做的方法是编写我的代码,尝试编译它,修复说我必须通过添加和号和星号传递指针的错误,直到错误通过。然而,我觉得这种对指针的半理解概念很快就会在某一天咬我。


红颜莎娜
浏览 162回答 3
3回答

慕标5832272

顾名思义,指针是指向内存中某个位置的变量。您在复制对象的整个值由于某种原因不合理时使用它。这可能是因为一个对象太大以至于复制它会很慢,所以您只想将一个小指针传递给该对象并在内存中使用相同的对象(可能是 http.Request 是一个指针的原因),或者因为您需要修改对代码中其他地方可能已经引用的对象的现有引用。您可以在此处查看net/http 的代码以了解原因。(事实上,对于任何 Go 标准库,如果你想研究为什么或如何以某种方式完成某事,代码是开放的。)但这有点无关紧要,因为作为用户,您传递指针的原因是因为函数被定义为将指针作为参数。编写库的程序员决定使用指针的原因是什么并不重要。您可以查找 go 文档,或者您可以做您正在做的事情,并且只传递一个值,如果编译器抱怨修复它。

九州编程

当您只是了解它们的工作原理时,指针是非常简单的概念,但是在理解之前,它确实看起来很难且令人讨厌,尤其是在 C 中。有指针算术、指向指针的指针等。无论如何,您不必使用指针,如果您的库不强制您使用,但由于函数作用域的原因,传递变量、函数周围的数据结构可能会将所有内容复制到另一个内存部分。在大多数语言中,值是通过文字传递的。这意味着当您将变量传递给函数或类时,它可能会复制它。更多的内存消耗,也需要 CPU 时间来复制项目。不利于复杂性。另一方面,像 PHP 这样的一些语言有一些自动化,比如copy on write algorithm当你将一个参数传递给它通过引用传递的函数时,它只将内存地址传递给函数,直到函数尝试写入这个变量,在那个时候它只是复制变量.但自动化也会带来一些成本。costGo的真正重点是尽可能快,少自动化,多用户控制,但也尝试安全和简单。不像 C、C++,它不会让你感到羞耻。在您的示例中,http.ResponseWriter当您通过其内存引用(作为指针)将其传递给 any 函数时,您在此函数内向其写入内容,它只是直接写入它,没有特殊算法或检查是否没有类型不匹配等. 可能有一些像垃圾收集器这样的检查,但它确实带来了好处而不是成本。同样在 PHP 中,Java 对象通过它们的引用传递,但该语言只是隐藏了这种冗长。我读过接口实际上是指针不完全Interface{}是,Go 中是基类型,所以每个类型都实现了接口类型,从这个角度来看,它只是一个类型,因此作为指针调用没有任何意义。它给你一个活力,例如:如果你从一个数据没有结构化和不一致的源读取,结构可以随时改变,例如 XML 或 JSON 源。只需使用界面!您已经知道每种类型的祖先都是接口,它只会在运行时处理数据的底层结构/类型。但是您也可以使用接口术语来定义接口(如 java、c#、php 等)并放置实现方法。当任何满足这些方法的结构体时。它自然地实现了接口。此实现设计称为 Duck Typing,请阅读以获取更多信息https://en.wikipedia.org/wiki/Duck_typing

慕斯709654

您可以将指针视为指向对象内存地址的值。与大多数数据结构相比,指针很小(比如 8 个字节)。很多时候你会得到一个指向对象的指针,因为传递这 8 个字节比创建你想要传递的整个对象的副本要快得多。在 Request 对象的情况下,与仅传递可以访问原始数据的指针相比,创建请求下所有内容的副本(有效负载、标头等)的成本非常高。
随时随地看视频慕课网APP

相关分类

Go
我要回答