为了账号安全,请及时绑定邮箱和手机立即绑定

返回泛型类型的默认值

返回泛型类型的默认值

Go
www说 2022-10-24 15:03:29
你如何返回nil一个泛型类型T?func (list *mylist[T]) pop() T {    if list.first != nil {        data := list.first.data        list.first = list.first.next        return data    }    return nil}func (list *mylist[T]) getfirst() T {    if list.first != nil {        return list.first.data    }    return nil}我收到以下编译错误: cannot use nil as T value in return statement
查看完整描述

3 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

您不能返回nil任何类型。例如,如果int用作类型参数,则T返回nil没有意义。nil也不是结构的有效值。


您可能会做的——以及有意义的事情——是为用于 的类型参数返回零值T。例如,零值nil用于指针、切片,它是空字符串string,0用于整数和浮点数。


如何返回零值?只需声明一个类型的变量T,然后返回它:


func getZero[T any]() T {

    var result T

    return result

}

测试它:


i := getZero[int]()

fmt.Printf("%T %v\n", i, i)


s := getZero[string]()

fmt.Printf("%T %q\n", s, s)


p := getZero[image.Point]()

fmt.Printf("%T %v\n", p, p)


f := getZero[*float64]()

fmt.Printf("%T %v\n", f, f)

哪些输出(在Go Playground上尝试):


int 0

string ""

image.Point (0,0)

*float64 <nil>


查看完整回答
反对 回复 2022-10-24
?
FFIVE

TA贡献1797条经验 获得超6个赞

*new(T)成语_

这已被建议作为 golang-nuts 中的首选选项。如果/当一些零值内置被添加到语言中时,它可能不太可读,但更容易找到和替换。


它还允许单行赋值。


new内置函数为任何类型的变量分配存储空间并返回指向它的指针,因此取消引用*new(T)有效地为T. 您可以使用类型参数作为参数:


func Zero[T any]() T {

    return *new(T)

}

如果T是可比较的,这可以方便地检查某个变量是否为零值:


func IsZero[T comparable](v T) bool {

    return v == *new(T)

}

var类型T

直截了当且更易于阅读,尽管它总是需要多一行:


func Zero[T any]() T {

    var zero T

    return zero

}

命名返回类型

如果您不想显式声明变量,则可以使用命名返回。不是每个人都喜欢这种语法,尽管当你的函数体比这个人为的例子更复杂时,或者如果你需要在defer语句中操作值时,这可能会派上用场:


func Zero[T any]() (ret T) {

    return

}


func main() {

    fmt.Println(Zero[int]())               // 0

    fmt.Println(Zero[map[string]int]())    // map[]  

    fmt.Println(Zero[chan chan uint64]())  // <nil>

}

命名返回的语法不可能与 var 声明的语法非常相似。


使用您的示例:


func (list *mylist[T]) pop() (data T) {

    if list.first != nil {

        data = list.first.data

        list.first = list.first.next

    }

    return

}

返回nil不可空类型

如果您真的想这样做,如您的问题中所述,您可以明确返回*T。


当类型参数T被限制为不包括指针类型的东西时,可以做到这一点。在这种情况下,您可以将返回类型声明为*T,现在您可以返回nil,这是指针类型的零值。


// constraint includes only non-pointer types

func getNilFor[T constraints.Integer]() *T {    

    return nil

}


func main() {

    fmt.Println(reflect.TypeOf(getNilFor[int]()))    // *int

    fmt.Println(reflect.TypeOf(getNilFor[uint64]())) // *uint64

}

让我再次声明一下:当不受任何允许指针类型的限制时,这最有效,T否则你得到的是指针到指针类型:


// pay attention to this

func zero[T any]() *T {

    return nil

}


func main() {

    fmt.Println(reflect.TypeOf(zero[int]()))  // *int, good

    fmt.Println(reflect.TypeOf(zero[*int]())) // **int, maybe not what you want...

}


查看完整回答
反对 回复 2022-10-24
?
哔哔one

TA贡献1854条经验 获得超8个赞

您可以初始化一个空变量。


if l == 0 {

        var empty T

        return empty, errors.New("empty Stack")

    }


查看完整回答
反对 回复 2022-10-24
  • 3 回答
  • 0 关注
  • 279 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号