我正在尝试实现一个返回基于原始结构的修改结构的方法,例如:
;WITH myCTE
AS ( SELECT T1.Year ,
T1.Month ,
T1.CarNumberID ,
T1.CarDepartedDateTime ,
T1.CarDepartedNumberID ,
LEAD(T1.CarDepartedDateTime) OVER ( ORDER BY T1.id ) AS [NextCarDepartureTime] ,
LEAD(T1.CarNumberID) OVER ( ORDER BY T1.id ) AS [NextCarNumberID]
FROM Test T1
)
SELECT * ,
DATEDIFF(HOUR, CarDepartedDateTime, NextCarDepartureTime) AS TurnAroundTime
FROM myCTE;
我收到以下错误:
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
})
}
任何帮助都将不胜感激。
答案 0 :(得分:4)
如果你想使用匿名结构返回值,那将会看起来很丑陋。
为什么呢?因为在定义返回类型时,必须描述匿名结构。当你编写一个return
语句时,你必须提供一个返回值,它将是一个struct literal。匿名结构的结构文字也必须描述结构!
当你试图写这个:
func (p *Project) OmitUsername() *struct {
// return somethig
}
这种语法不是您的想法:它不包含结构定义。基本上在您的示例中,第一个{
是匿名结构定义的左括号,而不是是函数体的左括号。因此,后续的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
}
如果你还添加了必须重复匿名结构定义的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
,并且为了返回某些东西,你必须初始化它,这也需要重复匿名结构!如果使用非指针,命名返回值,您将立即获得匿名结构的值,并且您不必再次重复匿名结构定义,只需为其字段赋值:
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())
输出(在Go Playground上尝试这些):
&{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())
输出(在Go Playground上尝试此操作):
{1 bobie <nil> <nil>}
注意:强>
嵌入并不是必需的,但这样就可以提升嵌入类型(BaseProject
)的字段,因此您可以像p.Id
一样引用它们,就像它们在{{1}中定义一样}}。将其定义为常规字段也可以。
答案 1 :(得分:3)
The Go Programming Language Specification
以下关键字是保留的,不得用作标识符。
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
func (p *Project) OmitUsername() *struct {
}
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() {}