【问题标题】:When is a pointer idiomatic?什么时候是指针惯用语?
【发布时间】:2016-01-25 19:02:55
【问题描述】:

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

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

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

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

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

我现在这样做的方法是编写我的代码,尝试编译它,修复那些说我必须通过添加一个&符号和星号来传递指针的错误,直到错误通过。但是,我觉得这种半知半解的指针概念很快就会在不久的将来咬我一口。

【问题讨论】:

  • 接口实现使用指针,但接口本身不是指针。

标签: pointers go


【解决方案1】:

您可以将指针视为指向对象内存地址的值。与大多数数据结构相比,指针很小(比如 8 个字节)。

很多时候你会得到一个指向对象的指针,因为传递这 8 个字节比创建你想要传递的整个对象的副本要快得多。

在请求对象的情况下,与仅传递可以访问原始数据的指针相比,创建请求下所有内容(有效负载、标头等)的副本会非常昂贵。

【讨论】:

  • 注意不要假设复制指针总是比复制结构快。由于 cpu 缓存等原因,在某些情况下复制指针可能会变慢。
【解决方案2】:

顾名思义,指针是指向内存中某个位置的变量。

当复制对象的整个值由于某种原因不合理时使用它。这可能是因为一个对象太大以至于复制它会很慢,所以您只想将一个小指针传递给该对象并在内存中使用相同的对象(可能是 http.Request 是指针的原因),或者因为您需要修改对代码中其他位置可能已经引用的对象的现有引用。您可以查看 net/http here 的代码以了解原因。 (事实上​​,对于任何 Go 标准库,如果您想了解为什么或如何以某种方式完成某事,代码都是开放的。)

但这有点无关紧要,因为作为用户,您传递指针的原因是因为函数被定义为将指针作为参数。编写库的程序员决定使用指针的原因无关紧要。您可以查找 go doc,也可以做您正在做的事情,只需传递一个值,如果编译器抱怨修复它。

【讨论】:

    【解决方案3】:

    当您只是了解它们的工作原理时,指针是一个非常简单的概念,但在理解之前,它看起来确实很困难且令人讨厌,尤其是在 C 中。有指针算术,指向指针的指针等。

    无论如何,如果您的库不强制您使用,您不必使用指针,但是传递变量,函数周围的数据结构可能会因为函数范围而将所有东西复制到另一个内存部分。

    在大多数语言中,值都是通过文字传递的。这意味着当您将变量传递给函数或类时,它可能会复制它。

    更多的内存消耗,也需要CPU时间来复制项目。不利于复杂性。

    另一方面,像 PHP 这样的一些语言有一些自动化,比如copy on write algorithm,当你将参数传递给它通过引用传递的函数时,它只会将内存地址传递给函数,直到函数尝试写入这个变量,在那个时间它只是复制变量。

    但自动化也会带来一些成本。 cost Go 的真正意义在于,它试图尽可能快地减少自动化,更多的用户控制,但也试图做到安全和简单。不像 C,C++ 不会让你感到羞耻。

    在您的示例http.ResponseWriter 中,当您通过其内存引用(作为指针)将其传递给任何函数时,您在此函数内向它写入内容,它只是直接写入它,没有特殊算法或检查是否没有类型不匹配等。可能会有一些像垃圾收集器这样的检查,但它确实带来的好处多于成本。

    同样在 PHP 中,Java 对象通过引用传递,但该语言只是隐藏了这种冗长。

    我读到接口实际上是指针

    不完全是,Interface{} 在 Go 中是一个基类型,所以每个类型都实现了接口类型,从这个角度来看,它只是一个类型,所以没有意义作为指针调用。 它为您提供了活力,例如:如果您从数据没有结构化和不一致的源中读取,则结构可以随时更改,例如 XML 或 JSON 源。只需使用接口!您已经知道每个类型的祖先都是接口,它只会在运行时处理底层结构/数据类型。

    但您也可以使用接口术语来定义接口(如 java、c#、php 等)并放置实现方法。当满足这些方法的任何结构时。它自然实现了接口。此实现设计称为 Duck Typing,请阅读以获取更多信息https://en.wikipedia.org/wiki/Duck_typing

    【讨论】:

      猜你喜欢
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 2012-02-01
      相关资源
      最近更新 更多