Constant struct in Go

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

Constant struct in Go

问题

为什么我不能创建常量结构体?

const FEED_TO_INSERT = quzx.RssFeed{ 0,
"",
"desc",
"www.some-site.com",
"upd_url",
"img_title",
"img_url",
0,
0,
0,
0,
0,
100,
"alt_name",
1,
1,
1,
"test",
100,
100,
0 }

.\rss_test.go:32: 常量初始化器 quzx.RssFeed 字面值不是常量

英文:

Why can't I create constant struct?

const FEED_TO_INSERT = quzx.RssFeed{ 0,
				    "",
				    "desc",
	                "www.some-site.com",
				    "upd_url",
				    "img_title",
				    "img_url",
				    0,
				    0,
				    0,
				    0,
				    0,
				    100,
				    "alt_name",
				    1,
				    1,
				    1,
				    "test",
				    100,
				    100,
				    0 }

> .\rss_test.go:32: const initializer quzx.RssFeed literal is not a constant

答案1

得分: 101

由于Go语言不支持结构体常量(我强调)

Go语言支持布尔常量、字符常量、整数常量、浮点数常量、复数常量和字符串常量。
字符常量、整数常量、浮点数常量和复数常量统称为数值常量。

在这里阅读更多信息:https://golang.org/ref/spec#Constants

英文:

Because Go does not support struct constants (emphasis mine)

> There are boolean constants, rune constants, integer constants,
> floating-point constants, complex constants, and string constants.

> Rune, integer, floating-point, and complex constants are collectively
> called numeric constants.

Read more here: https://golang.org/ref/spec#Constants

答案2

得分: 27

一个很好的解决方法是将其包装在一个函数中。

func FEED_TO_INSERT() quzx.RssFeed {
    return quzx.RssFeed{ 0,
                    "",
                    "desc",
                    "www.some-site.com",
                    "upd_url",
                    "img_title",
                    "img_url",
                    0,
                    0,
                    0,
                    0,
                    0,
                    100,
                    "alt_name",
                    1,
                    1,
                    1,
                    "test",
                    100,
                    100,
                    0 }
}

注意:确保该函数始终返回一个新对象(或副本)。

英文:

A good workaround is to wrap it in a function.

func FEED_TO_INSERT() quzx.RssFeed {
    return quzx.RssFeed{ 0,
                    "",
                    "desc",
                    "www.some-site.com",
                    "upd_url",
                    "img_title",
                    "img_url",
                    0,
                    0,
                    0,
                    0,
                    0,
                    100,
                    "alt_name",
                    1,
                    1,
                    1,
                    "test",
                    100,
                    100,
                    0 }
}

Note: Make sure that the function is always returning a new object(or copy).

答案3

得分: 20

你应该将它声明为 var。

Go允许你在模块范围内声明和初始化全局变量。

Go没有不可变性的概念。'const'并不意味着防止变量发生变异或类似的事情。

英文:

You should declare it as a var.

Go allows you to declare and initialize global variables at module scope.

Go does not have any concept of immutability. 'const' is not meant as a way to prevent variables from mutating or anything like that.

答案4

得分: 0

你可以将结构体字段声明为私有的,然后创建 getter 方法。

type ImmutableType struct {
  immutableField string
}

func (p ImmutableType) GetImmutableField() string {
  return p.immutableField
}

如果这样做,字段本身将在模块外部无法访问,从而变得类似于不可变。

然而,

  • 这只能在结构体级别上完成,不能在声明变量时完成
  • 如果你想在模块外部实例化结构体,你还必须创建一个构造函数,这会变得有点混乱,因为构造函数在 Go 中并不是常用的做法。

为了“强制”使用你的构造函数,你还可以将结构体本身声明为私有的,这样就无法使用私有字段创建复合字面量。

type immutableType struct {
  immutableField string
}

func (p immutableType) GetImmutableField() string {
  return p.immutableField
}

func CreateImmutableType(immutableField string) immutableType {
  return immutableType{
    immutableField: immutableField,
  }
}

简而言之,Go 并没有不可变性作为核心概念,因此实现它需要大量的样板代码。

英文:

You could declare your struct fields as private and then create getter methods.

type ImmutableType struct {
  immutableField string
}

func (p ImmutableType) GetImmutableField() string {
  return p.immutableField
}

If you do this, the field itself will be inaccessible outside the module and will become sort of immutable.

However,

  • this can only be done on the struct level, not when declaring a variable
  • if you want to instantiate your struct outside of the module, you'll have to also create a constructor, which becomes kind of a mess since constructors are not really a commonly used practice in Go.

In order to "force" the use of your constructor, you might also declare your struct itself private, so it cannot be created as a composite literal without the private fields.

type immutableType struct {
  immutableField string
}

func (p immutableType) GetImmutableField() string {
  return p.immutableField
}

func CreateImmutableType(immutableField string) immutableType {
  return immutableType{
    immutableField: immutableField,
  }
}

TL;DR Go doesn't have immutability as a core concept, so implementing it requires a bunch of boilerplate.

答案5

得分: 0

正如所说,Go语言不支持常量结构体变量。这是有原因的,编译器无法确保任何结构体的不可变性(例如包含指针的结构体)。解决方案相当简单:只需使用普通变量:

type Person struct {
	age int
}

var Luke = Person{10}

你也可以使用匿名结构体:

var Andrew = struct {
	age int
}{
	age: 13,
}

当你将其作为全局变量创建时,请谨慎对待。另一个建议是使用函数始终返回一个副本,这是另一个极端的做法。

英文:

As was said, Go does not support constant struct variables. This has a reason, compiler cannot ensure immutability of any struct (e.g. containing a pointer). Solution is rather simple: just use normal variable:

type Person struct {
	age int
}

var Luke = Person{10}

You can also use anonymous struct:

var Andrew = struct {
	age int
}{
	age: 13,
}

When you create this as a global variable, treat it as that - with care. The other recommendation is to use a function to return always a copy and that is the other extreme.

huangapple
  • 本文由 发表于 2017年4月12日 19:44:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/43368604.html
匿名

发表评论

匿名网友

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

确定