一尘不染

在Go中引用字符串文字

go

在我的应用程序中,我将经常传递对静态字符串的引用。我希望避免让Go为每个调用分配内存,但是我无法将地址获取到字符串文字。

为什么不能采用字符串文字的地址(请参见test1()下面的示例)?我是否误解了语法,还是由于Go的内部运作而受到限制?

如果不可能的话,最好的解决方案是什么?

test2()可以,但是var hej每次都会分配内存吗?
test3()不会分配任何新的内存,但我希望避免该函数之外的混乱情况。

package main

import "fmt"

var konnichiwa = `こんにちは世界`

// Gives the compile error `cannot take the address of "Hello world"`
func test1() (*string) { return &`Hello world` }

// Works fine
func test2() (*string) {
    hej := `Hej världen`
    return &hej
}

func test3() (*string) { return &konnichiwa }

func main(){
    fmt.Println(*test1())
    fmt.Println(*test2())
    fmt.Println(*test3())
}

感谢帮助!


阅读 290

收藏
2020-07-02

共1个答案

一尘不染

接受文字(字符串,数字等)的地址是非法的,因为它的语义不明确。

您是否要使用实际常数的地址?这将允许修改值(并可能导致运行时错误),还是要分配新对象,将常量复制过来并将地址获取到新版本?

在这种情况下不存在这种歧义,test2因为您正在处理的语义已明确定义的现有变量。如果将字符串定义为,则将无法正常工作const

语言规范通过明确不允许您的要求来避免这种歧义。解决方法是test2。虽然稍微冗长一些,但它使规则保持简洁明了。

当然,每条规则都有其例外,在Go中,这涉及到复合文字:以下内容合法,并在规范中进行了定义:

func f() interface{} {
    return &struct {
        A int
        B int
    }{1, 2} 
}
2020-07-02