英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论