英文:
In golang, how to embed on custom type?
问题
我有自定义类型Int64Array
,Channel
和ChannelList
,如下所示:
type Int64Array []int64
func (ia *Int64Array) Scan(src interface{}) error {
rawArray := string(src.([]byte))
if rawArray == "{}" {
*ia = []int64{}
} else {
matches := pgArrayPat.FindStringSubmatch(rawArray)
if len(matches) > 1 {
for _, item := range strings.Split(matches[1], ",") {
i, _ := strconv.ParseInt(item, 10, 64)
*ia = append(*ia, i)
}
}
}
return nil
}
func (ia Int64Array) Value() (driver.Value, error) {
var items []string
for _, item := range ia {
items = append(items, strconv.FormatInt(int64(item), 10))
}
return fmt.Sprintf("{%s}", strings.Join(items, ",")), nil
}
type Channel int64
type ChannelList []Channel
我该如何将Int64Array
嵌入到ChannelList
中,以便可以在其上调用Scan
和Value
方法?我尝试了以下代码:
type ChannelList []Channel {
Int64Array
}
但是我得到了语法错误。重要的是确保ChannelList
的项是Channel
类型的。如果无法通过嵌入实现这一点,我可以创建独立的函数供ChannelList
和Int64Array
同时调用。
英文:
I have custom types Int64Array
, Channel
and ChannelList
like:
type Int64Array []int64
func (ia *Int64Array) Scan(src interface{}) error {
rawArray := string(src.([]byte))
if rawArray == "{}" {
*ia = []int64{}
} else {
matches := pgArrayPat.FindStringSubmatch(rawArray)
if len(matches) > 1 {
for _, item := range strings.Split(matches[1], ",") {
i, _ := strconv.ParseInt(item, 10, 64)
*ia = append(*ia, i)
}
}
}
return nil
}
func (ia Int64Array) Value() (driver.Value, error) {
var items []string
for _, item := range ia {
items = append(items, strconv.FormatInt(int64(item), 10))
}
return fmt.Sprintf("{%s}", strings.Join(items, ",")), nil
}
type Channel int64
type ChannelList []Channel
How can I embed Int64Array
to ChannelList
such that I can call Scan
and Value
methods on it? I tried the following:
type ChannelList []Channel {
Int64Array
}
but I'm getting syntax error. What's important is to make sure ChannelList
items are of type Channel
, if this isn't possible via embedding I might just create stand-alone functions to be called by both ChannelList
and Int64Array
.
答案1
得分: 3
匿名字段(或嵌入字段)出现在结构体中(参见struct
类型),而不是类型别名(或“类型声明”)中。
你不能在另一个类型声明中嵌入类型声明。
此外,正如“Go:使用指向数组的指针”的答案所示,你不应该使用指向切片的指针,而应直接使用切片本身(按值传递)。
Wessie在评论中友好地指出,(ia *Int64Array) Scan()
使用指向切片的指针来改变所引用的底层数组。
我更喜欢返回另一个切片而不是改变现有的切片。
话虽如此,Golang代码审查确实提到:
> 如果接收器是struct
、array
或slice
,并且其中任何一个元素是指向可能发生变化的内容的指针,请优先使用指针接收器,因为这将使意图对读者更加清晰。
英文:
An anonymous (or embedded field) is found in a struct (see struct
type), not in a type alias (or "type declaration").
You cannot embed a type declaration within another type declaration.
Plus, as illustrated by the answers to "Go: using a pointer to array", you shouldn't be using pointers to slice, use directly the slice themselves (passed by value).
Wessie kindly points out in the comments that (ia *Int64Array) Scan()
uses pointer to a slice in order to mutate the underlying array referenced by said slice.
I would prefer returning another slice instead of mutating the existing one.
That being said, the Golang Code Review does mention:
> If the receiver is a struct
, array
or slice
and any of its elements is a pointer to something that might be mutating, prefer a pointer receiver, as it will make the intention more clear to the reader.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论