【问题标题】:Get address after changing type更改类型后获取地址
【发布时间】:2019-04-15 14:18:11
【问题描述】:

我是 Go 新手,我正在尝试从开发人员的角度找到一种方便的方法,以便在更改类型后获取对象的地址。

考虑这两种新类型:

type specialString string
type nestedStruct struct {
    name *specialString
}

我找到的填充 nestedStruct 的规范方法是这样的:

str := "James"
specStr := specialString(str)
nested := nestedStruct{
    name: &specStr,
}

有没有办法省略specStr 的声明,然后只在一个地方使用?我试过这个,但它触发了一个语法错误(这是什么逻辑原因?):

//Syntax error
nested := nestedStruct{
    name: &specialString(str),
}

任何帮助将不胜感激。

【问题讨论】:

    标签: go


    【解决方案1】:

    您不能获取任意操作的地址,包括类型转换。详情见How can I store reference to the result of an operation in Go?;和Find address of constant in go

    如果你转换字符串文字,你可以省略局部变量之一:

    specStr := specialString("James")
    nested := nestedStruct{
        name: &specStr,
    }
    

    如果您已经有一个string 类型的变量,并且您想省略第二个变量(specialString 类型),则取现有string 变量的地址,并将其转换为*specialString

    str := "James"
    nested = nestedStruct{
        name: (*specialString)(&str),
    }
    

    Go Playground 上尝试这些示例。

    如果您想省略局部变量,请参阅此答案以获取选项:How do I do a literal *int64 in Go?

    【讨论】:

    • 非常感谢,第二种方法正是我需要的!
    【解决方案2】:

    使用函数在初始化时消除样板:

    func specialStringPtr(s string) *specialString { 
         return (*specialString)(&s) 
    }
    
    
    nested := nestedStruct{
        name: specialStringPtr(str),
    }
    

    【讨论】:

    • 这不会复制str 的值,从而产生不必要的性能开销吗?有没有办法以更通用的方式编写这样的函数,以便它接受多种类型并返回相应的指针?
    • 此方法复制字符串标头(指针、长度),但不复制后备字节数组。复制标头的性能成本可以忽略不计。解决此问题的任何方法都必须将字符串标头复制到变量中。
    • 更不用说这个简单的函数很可能被编译器内联了。
    • 查看AWS value and pointer conversion utilities 了解处理多种类型的一种方法。 AWS 为每种类型提供了一个帮助函数。
    • “这不会……造成不必要的性能开销吗?”也许,也许不是,但假设它会是没有意义的。编写代码,做它应该做的并且对阅读它的人有意义。如果您衡量一个性能问题,并分析以定位问题的根源,那么您可以担心优化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    相关资源
    最近更新 更多