How to declare an immutable variable in Go?

huangapple go评论77阅读模式
英文:

How to declare an immutable variable in Go?

问题

我正在解决一些练习题,以便在Go语言中进行一些实践,并遇到了以下问题。

考虑这个函数:

func foo(s string) {
    length := len(s);

    // 只是从length中读取一些内容
}

在这里,由于在其他语言中编程的经验,我立刻想到"length不会被修改,所以应该标记为const"。

所以我这样做了:

const length = len(s);

但是它给我返回了以下错误:

const initializer len(s) is not a constant

我猜这是因为len(s)不能在"编译时"计算出来(关于Go语言是否完全正确,我不太确定)。

有没有办法指示length不应该被修改?我在Google上搜索了一下,但没有找到有用的信息。我找到了一些关于不可变结构体的东西,但我觉得对于我想做的事情来说太复杂了。

英文:

I was solving some exercises to get some practice in go and came across the
following problem.

Take this function:

func foo(s string) {
    length := len(s);

    // Do something just reading from lenght
}

Here, thanks to programing in other languages, my mind immediately went "length
will not be modified, so it should be marked const".

So I did this:

const length = len(s);

But it gives me the following error:

const initializer len(s) is not a constant

I suppose that is because len(s) cant be calculated "at compile time" (Not
sure if this is 100% correct talking about go).

Is there any way to indicate that length should not be modified? I searched
in Google, but I found nothing usefull. I got some thins about immutable structs, but
I think its too complex for what I want to do.

答案1

得分: 8

你不能将变量指定为不可变的。只有常量具有这个属性。

在Go语言中,常量也是编译时常量,这意味着你不能将其初始化为依赖于某个变量的特定值,比如你示例中的s

此外,除了一些罕见的例外,函数不能返回常量。即使可以返回常量,它仍然必须是编译时常量。len函数可以返回一个常量值,但前提是参数具有固定大小,比如字符串常量或数组类型(在Go中具有固定长度)。

英文:

You cannot specify a variable to be immutable. Only constants have this property.

Constants in Go are also compile-time constant, meaning you can't initialize it to something that depends on the particular value of some variable like s in your example.

Also, with rare exceptions, functions cannot return constants. Even when they can, it must still be a compile-time constant. len can return a constant value, but only if the parameter is constantly sized, such as a string constant or of an array type (which has fixed length in Go).

答案2

得分: 2

对于具有类似结果的情况,您可以使用私有字段。创建一个类似下面的模块:

package foo

type Length struct { value int }

func NewLength(s string) Length {
   return Length{
      len(s),
   }
}

func (l Length) Int() int { return l.value }

然后像这样使用:

package main
import "foo"

func main() {
   l := foo.NewLength("north")
   println(l.Int() == 5)
   // l.value undefined (cannot refer to unexported field or method value)
   l.value = 6
}
英文:

For something with similar result, you could use a private field. Make a module
like this:

package foo

type Length struct { value int }

func NewLength(s string) Length {
   return Length{
      len(s),
   }
}

func (l Length) Int() int { return l.value }

then use like this:

package main
import "foo"

func main() {
   l := foo.NewLength("north")
   println(l.Int() == 5)
   // l.value undefined (cannot refer to unexported field or method value)
   l.value = 6
}

huangapple
  • 本文由 发表于 2021年6月22日 05:45:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/68075085.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定