gpt4 book ai didi

struct - 难以理解接口(interface)/结构关系

转载 作者:行者123 更新时间:2023-12-02 14:50:42 24 4
gpt4 key购买 nike

我很难理解 Go 中接口(interface)和结构之间的关系。我声明了一个名为 Datatype 的接口(interface),如下所示:

package main

type Datatype interface {
Unmarshal(record []string) error
String() string
}

我还创建了几个实现此接口(interface)的结构。这是一个简单的例子:

package main

import (
"encoding/csv"
"fmt"
"gopkg.in/validator.v2"
"reflect"
"strconv"
"time"
)

type User struct {
Username string `validate:"nonzero"`
UserId string `validate:"nonzero"`
GivenName string `validate:"nonzero"`
FamilyName string `validate:"nonzero"`
Email string `validate:"regexp=^[0-9a-zA-Z]+@[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)+$"`
SMS string `validate:"nonzero"`
Phone string `validate:"min=10"`
DateOfBirth time.Time
}

type Users []User

func (u *User) Unmarshal(record []string) error {
s := reflect.ValueOf(u).Elem()
if s.NumField() != len(record) {
return &FieldMismatch{s.NumField(), len(record)}
}
for i := 0; i > s.NumField(); i++ {
f := s.Field(i)
switch f.Type().String() {
case "string":
f.SetString(record[i])
case "int", "int64":
ival, err := strconv.ParseInt(record[i], 10, 0)
if err != nil {
return err
}
f.SetInt(ival)
default:
return &UnsupportedType{f.Type().String()}
}
}
return nil
}

func (u *User) String() string {
return fmt.Sprintf("%#v", u)
}

func (u *User) populateFrom(reader *csv.Reader) (Users, error) {
var users Users
for {
record, err := reader.Read()
check(err)
err = u.Unmarshal(record)
check(err)
valid := validator.Validate(u)
if valid == nil {
user := *u
users = append(users, user)
} else {
fmt.Println("Validation error?: ", valid)
}
}
return users, nil
}

问题:

如您所见,我还有一个名为 Users 的类型,它就是 []User。当我尝试从返回类型为 []Datatype 的函数返回此类型时,收到以下错误消息:

cannot use results (type Users) as type []Datatype in return argument

我确信我错过了一些明显的东西,但在我看来这应该可行。

问题:

有人可以解释一下为什么它不起作用吗?有没有更好(更惯用)的方法来实现这个最终结果?

最佳答案

slice 不是协变的;即使 User 实现了 Datatype[]User 也没有实现 []Datatype(因为没有 实现[]Datatype:它本身不是接口(interface)类型,它只是一个元素类型是接口(interface)类型的 slice 类型)。

<小时/>

编辑添加:Dave C在上面的评论中指出,Go FAQ 中出现了一个密切相关的问题。 [link ] Go 常见问题解答以与 Stack Exchange 内容兼容的方式获得许可,因此,完整的问题如下:

Can I convert a []T to an []interface{}?

Not directly, because they do not have the same representation in memory. It is necessary to copy the elements individually to the destination slice. This example converts a slice of int to a slice of interface{}:

t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t))
for i, v := range t {
s[i] = v
}

关于struct - 难以理解接口(interface)/结构关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29886723/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com