专栏名称: GoCN
最具规模和生命力的 Go 开发者社区
目录
相关文章推荐
北京晚报  ·  补时遭绝杀!遗憾……但要看到希望 ·  昨天  
北京晚报  ·  补时遭绝杀!遗憾……但要看到希望 ·  昨天  
青岛新闻网  ·  U20国青被绝杀 ·  昨天  
青岛新闻网  ·  U20国青被绝杀 ·  昨天  
51好读  ›  专栏  ›  GoCN

Go 1.22 的新增功能系列之二:reflect.TypeFor

GoCN  · 公众号  ·  · 2024-04-28 09:48

正文

Go 1.22 的第一个候选版本已经发布,这意味着最终版本即将发布,现在是我在博客中介绍我在这个周期中所做工作的时候了。像往常一样,我的贡献很小,但它们是我的,所以我将从幕后的角度来谈谈它们。首先是reflect.TypeFor。

这是整个函数:

// TypeFor returns the [Type] that represents the type argument T.func TypeFor[T any]() Type {  return TypeOf((*T)(nil)).Elem()}

很简单!测试代码比实际函数本身长大约十倍。

当您想要为某种类型创建 reflect.Type 对象时,例如 var intType = reflect.TypeFor[int]() var errorType = reflect.TypeFor[error]() ,请使用此函数。

将其添加到反射包中的提案由 Josh Bleecher Snyder 提出。它标志着泛型通过标准库的不断进步又迈出了一步。

该提案最困难的部分可能是为该函数找到正确的名称。 reflect.TypeOf 将是该函数最自然的名称,但它已被现有函数用于创建 reflect.Type 对象。考虑的替代方案包括:

  • StaticTypeOf

  • MakeType

  • TypeOfT

  • TypeFrom

  • GetType

  • AsType

  • ToType

  • NewType

  • TheType

  • Types

  • ConstantType

  • T

命名事物仍然是计算机科学中的两个难题之一。

我扔掉了获胜的名字,但那时我们只是浏览所有可能的形容词和介词的列表,所以最终有人会选择 TypeFor

总的来说,我反对“无用地使用泛型”,即使用泛型函数,即使它没有添加任何类型安全性并且没有或只有最小的长度节省。例如,制作 json.Marshal 的泛型版本对泛型来说是无用的,因为它实际上并没有添加任何类型安全性。然而,在这种情况下,为接口构建 reflect.Type 的正确方法相当模糊,所以我认为值得添加。

这个问题可以追溯到 Go 中的反射第一定律:“反射从接口值到反射对象。”当您调用 reflect.TypeOf(0) 时,您会得到您所期望的:类型 int reflect.Type 对象。但如果您致电 reflect.TypeOf(err) ,您可能会对所得到的结果感到惊讶。您不会获取包含类型 error 的对象,而是获取具有底层具体类型 err 的对象。这是因为 error 是一个接口值,而 Go 中调用函数时,函数的接口参数会根据需要进行转换,所以错误接口丢失,只有具体值对 reflect.TypeOf 。更糟糕的是,如果







请到「今天看啥」查看全文