C ++中的Const引用和Golang中的等效引用

时间:2016-04-11 14:40:06

标签: go

我来自C ++世界和C ++,通常当你关心性能而你不需要改变对象时,你使用常量引用传递它

CONFIG      += plugin debug_and_release
TARGET      = $$qtLibraryTarget(WidgetBoxPlugin)
TEMPLATE    = lib
...
target.path = $$[QT_INSTALL_PLUGINS]/designer
creator_target.path = $$[QTCREATOR_BIN_PATH]/plugins/designer
INSTALLS    += target creator_target

在这种情况下,字符串未被复制,无法在函数中修改。

我知道,在Go中有两种传递对象的方法:

  • 按价值,然后你不能修改(或实际上你可以,但没有任何意义)它,但它非常耗费内存
  • 通过指针,这可以从内存条款中获得好处,但您可以修改对象。

那么,最好的方法是什么?即使您不想修改它也总是通过指针传递对象,因为它更快?或者有一些编译器优化,即使你按值发送它有时它也会作为参考发送?

2 个答案:

答案 0 :(得分:4)

在Go中没有直接的等价物。

  1. 如果对象很大(〜大于32-64字节)和/或需要更改,则通过指针传递。
  2. 如果上述规则不适用,则按值传递。
  3. maps / channels / slices是引用类型,它们包含内部指针,所以你不需要通过指针传递它们,除非你计划传递一个nil或想要追加(不修改已经包含的元素)切片。
  4. 示例:

    func doMap(m *map[string]string) {
        if *m == nil {
            *m = map[string]string{}
        }
        .....
    }
    

答案 1 :(得分:0)

对于字符串,您可以使用*string作为参数,似乎您无法更改原始字符串:

package main

import (
    "fmt"
    )

func t1(s *string) {
    fmt.Println("Inside before: %s", *s)
    s2 := "tEsT1"
    s = &s2
    fmt.Println("Inside after 1: %s", *s)
}

func main() {
    var s = "test"
    fmt.Println("Ourside before: %v", s)
    t1(&s)
    fmt.Println("Ourside  after: %v", s)
}

打印:

Ourside before: %v test
Inside before: %s test
Inside after 1: %s tEsT1
Ourside  after: %v test

对于复杂的结构,它将更难或不可能通过ref& amp;阻止编辑。

如果我弄错了,请纠正我(我只是学习Go )。