如果我有一个返回
T any
的函数,但在某些情况下我需要返回 nil
,那么可以返回指针 *T 吗?或者有更好的解决方案
func GetData[T any](item T) *T {
res := New[T](item)
return &res
}
这样做可以可以,但也有不同的解决方案;它们是否更好是主观的和情境的。
一种替代方案,在通用函数真正通用的情况下可能被认为是“更好”——也就是说,可以与任何类型参数一起使用,即使用附加标志返回零值而不是
nil
值或错误(视情况而定)以指示何时忽略零值:
func GetData[T any](item T) (res T, exists bool) {
// .. locate "item" and setting exists true ..
// .. and updating "res" if found ..
// .. if not found, res and exists should be ..
// .. left at their automatic zero values which ..
// .. means false for exists ..
return
}
使用中:
res, ok := GetData(item)
if !ok {
// appropriate handling
}
// otherwise, we have a valid res
这允许零值可能是有效结果而不是指示不存在结果的情况。
将指针传递给一个值来接收可能是引用类型的结果可能被认为更可接受(例如,参见:
json.Unmarshal()
),因此如果使用指针使事情在您的情况下变得更容易,这可能是比返回一个指针(尽管在这种情况下你几乎肯定还需要一个“有效结果”标志):
func GetData[T any](item T, dest *T) bool {
// ...
}
在权衡这些替代方案时,请考虑问题评论中提出的问题。
特别是,如果该函数可以与类型参数一起使用,而返回指针会使所使用的类型已经是引用类型的情况变得复杂,那么在这些情况下这可能会导致不必要的复杂/不惯用的代码,因此被认为是不可取的,例如与您当前的功能:
b := GetData[[]byte](a)
if len(b) == 0 { // ERROR: len cannot be used with a *[]byte
}
在这种情况下,传递一个指向值的指针来接收结果,而不是返回结果可能更可取。
d := []byte{}
_ = GetData[[]byte](a, &d)
// we might need to check the returned flag in other cases, but with
// []byte type argument we can ignore it if all we are concerned with
// is whether the resulting slice is empty or not
if len(d) == 0 {
}
我还要补充一点,如果在未来存在潜力,即使该函数当前未与此类类型一起使用,有关的担忧也适用。
仅当用法确定仅限于适当但当前无法约束的[语言]类型时,您才应继续返回指针。
恕我直言