Struct 意外返回匿名结构
我正在尝试实现一个方法,该方法返回基于原始结构的修改结构,例如:Struct 意外返回匿名结构,struct,go,Struct,Go,我正在尝试实现一个方法,该方法返回基于原始结构的修改结构,例如: type Project struct { Username string Id uint Alias string Data *json.RawMessage Scheme Scheme } func (p *Project) OmitUsername() *struct {
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
})
}
我得到以下错误:
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
任何帮助都将不胜感激。
以下关键字是保留的,不能用作标识符
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
struct
是保留关键字
如果没有更多关于你想做什么的信息,你很难知道你想要什么,也许是这样的
package main
import (
"encoding/json"
)
type Scheme struct{}
type Project struct {
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
}
type UserProject struct {
Username string
Project
}
func (u *UserProject) GetProject() *Project {
return &u.Project
}
func main() {}
使用“真正”匿名结构返回值
如果你想使用匿名结构返回值,那看起来会很难看
为什么??因为在定义返回类型时,必须描述匿名结构。在编写return
语句时,必须提供返回值,返回值将是一个struct literal。匿名结构的结构文字还必须描述该结构
当您尝试写入以下内容时:
func (p *Project) OmitUsername() *struct {
// return somethig
}
此语法与您的想法不同:它不包含结构定义。基本上,在您的示例中,第一个{
是匿名结构定义的开始括号,不是函数体的开始括号。因此,后续的返回
被解释为在匿名结构定义内,这是无效语法,这也正是错误消息所述(“语法错误:意外返回”
)
应该是这样的:
func (p *Project) OmitUsername() *struct {
Id uint
Alias string
Data *json.RawMessage
Scheme Scheme
} {
// And now here comes the return statement
}
如果还添加了必须重复匿名结构定义的return语句:
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}
}
是的,它很难看。您可以通过使用命名返回值而不返回指针来简化它,因为指针的零值是nil
,若要返回某个值,您必须对其进行初始化,这还需要重复匿名结构!若您使用非指针,命名为返回值,您的值将为onymous结构,您不必再次重复匿名结构定义,只需为其字段赋值:
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
}
使用它们:
p := Project{"Bob", 1, "bobie", nil, nil}
fmt.Println(p.OmitUsername())
fmt.Println(p.OmitUsername2())
输出(请在上尝试这些选项):
使用它:
p := Project{BaseProject{1, "bobie", nil, nil}, "Bob"}
fmt.Println(p.OmitUsername())
输出(在上尝试此操作):
{1 bobie}
注意:
实际上,嵌入不是必需的,但通过这种方式,嵌入类型的字段(
BaseProject
)将被提升,因此您可以像p.Id
一样引用它们,就像它们是在Project
中定义的一样。将其定义为常规字段也会起作用。是的,这正是我想要的。为什么我首先要使用struct
作为返回类型!?虽然您的答案非常清楚简洁,但我必须标记@icza的作为正确的一个,因为它更复杂,而且实际上首先提供了嵌入式类型解决方案。尽管如此,还是很感激。谢谢!你的回答非常复杂,为我打开了新的知识。因此,结构
不是没有定义的类型!这是我以前从未知道过的。但是,嵌入式类型确实引入了更多的为项目
声明新值时的简单性。
&{1 bobie <nil> <nil>}
{1 bobie <nil> <nil>}
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
}
p := Project{BaseProject{1, "bobie", nil, nil}, "Bob"}
fmt.Println(p.OmitUsername())
{1 bobie <nil> <nil>}