我正在尝试实现一种基于原始结构返回修改后的结构的方法,例如:
type Project struct {
Username string
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
}
func (p *Project) OmitUsername() *struct {
return &struct {
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
}{
p.Id,
p.Alias,
p.Data,
p.Scheme
})
}
Run Code Online (Sandbox Code Playgroud)
我得到以下错误:
models/project.go:22: syntax error: unexpected return
models/project.go:24: non-declaration statement outside function body
models/project.go:25: non-declaration statement outside function body
models/project.go:25: syntax error: unexpected string literal, expecting semicolon or newline
models/project.go:26: non-declaration statement outside function body
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激。
如果要使用匿名struct返回值,那看起来真的很丑。
为什么?因为在定义返回类型时,必须描述匿名结构。而且,当您编写return语句时,必须提供返回值,该返回值将是结构文字。匿名结构的结构文字也必须描述该结构!
当您尝试编写此代码时:
func (p *Project) OmitUsername() *struct {
// return somethig
}
Run Code Online (Sandbox Code Playgroud)
这种语法与您的想法无关:它不包含struct定义。基本上在您的示例中,第一个{是匿名struct定义的左括号,而不是函数主体的左括号。因此,后续return语句被解释为位于无效语法的匿名结构定义中,这也正是错误消息指出的内容("syntax error: unexpected return")。
它看起来应该像这样:
func (p *Project) OmitUsername() *struct {
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
} {
// And now here comes the return statement
}
Run Code Online (Sandbox Code Playgroud)
如果还添加了return语句,该语句必须重复匿名struct定义:
func (p *Project) OmitUsername() *struct {
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
} {
return &struct {
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
}{p.Id, p.Alias, p.Data, p.Scheme}
}
Run Code Online (Sandbox Code Playgroud)
是的,这很丑。您可以通过使用命名的返回值而不返回指针来简化操作,因为指针的零值为nil,并且要返回某些内容,则必须对其进行初始化,这也将涉及重复匿名结构!如果使用名为返回值的非指针,则将立即拥有匿名结构的值,并且不必再次重复匿名结构定义,只需将值分配给其字段即可:
func (p *Project) OmitUsername2() (ret struct {
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
}) {
ret.Id = p.Id
ret.Alias = p.Alias
ret.Data = p.Data
ret.Scheme = p.Scheme
return
}
Run Code Online (Sandbox Code Playgroud)
使用它们:
p := Project{"Bob", 1, "bobie", nil, nil}
fmt.Println(p.OmitUsername())
fmt.Println(p.OmitUsername2())
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上尝试这些):
&{1 bobie <nil> <nil>}
{1 bobie <nil> <nil>}
Run Code Online (Sandbox Code Playgroud)
还是很丑
...最好是提供另一个要返回的命名类型,而不是匿名结构。您可以利用嵌入使该解决方案实用且简短:
type BaseProject struct {
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
}
type Project struct {
BaseProject
Username string
}
func (p *Project) OmitUsername() BaseProject {
return p.BaseProject
}
Run Code Online (Sandbox Code Playgroud)
使用它:
p := Project{BaseProject{1, "bobie", nil, nil}, "Bob"}
fmt.Println(p.OmitUsername())
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上尝试):
{1 bobie <nil> <nil>}
Run Code Online (Sandbox Code Playgroud)
注意:
嵌入并不是真正必要的方法,但是通过这种方式,BaseProject可以提升嵌入类型()的字段,因此您可以像p.Id在中定义它们一样对其进行引用Project。将其定义为常规字段也可以。
| 归档时间: |
|
| 查看次数: |
1884 次 |
| 最近记录: |