是否可以从分配给什么返回值来推断类型参数?

2023-12-27

假设我写了两个这样的函数:

func ToInterfaceSlice[T any](s []T) []interface{} {
    res := make([]interface{}, len(s))
    for i, v := range s {
        res[i] = v
    }
    return res
}

func FromInterfaceSlice[T any](s []interface{}) (res []T, err error) {
    res = make([]T, len(s))
    for i, v := range s {
        vt, ok := v.(T)
        if !ok {
            return nil, fmt.Errorf("%v (type=%T) doesn't fit the target type %T", v, v, res)
        }
        res[i] = vt
    }
    return
}

当我从输入参数解析类型时,我可以简单地使用

    var m = []int{1, 2, 3}
    fmt.Println(ToInterfaceSlice(m))

编译器知道T is int.

但是,当我尝试从返回变量传递类型时

    var m []int
    m, _ = FromInterfaceSlice([]interface{}{1, 2, 3})
    fmt.Println(m)

编译器给出错误:

.\scratch.go:29:27: 无法推断 T

我必须在函数调用中显式传递类型:

    var m []int
    m, _ = FromInterfaceSlice[int]([]interface{}{1, 2, 3})
    fmt.Println(m)

当接收者变量不是接口时,是否有什么难以从返回类型推断类型参数的事情?还是只是不执行,甚至故意不执行?

评论后更新 #1

我知道a, b := GenericFunc()无法引用返回值的类型。目前,Go 确实有“视情况而定”的情况,是否需要用户输入的显式实例化。

type Set[T comparable] map[T]struct{}

func NewSet[T comparable](eles ...T) Set[T] {
    s := make(Set[T])
    for _, ele := range eles {
        s[ele] = struct{}{}
    }
    return s
}

两者都用就可以了t := NewSet(1, 2, 3) and t := NewSet[string](), 但不是var t NewSet[float64] = NewSet()现在因为这个


当前类型推断的规则是explicit https://go.dev/ref/spec#Type_inference。不考虑如何使用返回值:

类型推断基于

  • 类型参数列表
  • 使用已知类型参数初始化的替换映射 M(如果有)
  • 普通函数参数的(可能为空)列表(仅在函数调用的情况下)

从 Go 1.18 开始,您可能会简单地重写您的函数以接受所需类型的参数;这还有一个好处,就是不隐藏函数体内的分配:

func FromInterfaceSlice[T any](s []interface{}, dst []T) error {
    if len(s) != len(dst) {
        return errors.New("lengths don't match")
    }
    for i, v := range s {
        vt, ok := v.(T)
        if !ok {
            return nil, fmt.Errorf("%v (type=%T) doesn't fit the target type %T", v, v, res)
        }
        dst[i] = vt
    }
    return nil
}

并传入具有所需长度的目标切片:

func main() {
    src := []interface{}{1, 2, 3}
    m := make([]int, len(src))
    _ = FromInterfaceSlice(src, m)
    fmt.Println(m)
}

如果您不能或不想预先确定切片的长度,则只能进行显式实例化:

var m []int
m, _ = FromInterfaceSlice[int]([]interface{}{1, 2, 3})
//                        ^^^ explicit type argument

而且类型参数仍然无法推断:=简写声明:

// what is m???
m, err := FromInterfaceSlice([]interface{}{1, 2, 3})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以从分配给什么返回值来推断类型参数? 的相关文章

  • Go SQL查询不一致

    我在执行查询时遇到一些非常奇怪的不一致 并且想知道是否有人知道原因 想象一下我有一个定义如下的结构 type Result struct Afield string db A Bfield interface db B Cfield str
  • 如何在 Go 中表示可选字符串?

    我希望建模一个可以有两种可能形式的值 不存在或字符串 执行此操作的自然方法是Maybe String or Optional
  • GO并发编程测试

    我试图确保我的并发程序不存在以下情况 僵局 livelock 饥饿 我找到了以下工具http blog golang org race detector http blog golang org race detector 我尝试编译并运行
  • 给定方法值,获取接收者对象

    Go 有没有办法从方法值获取接收者对象 例如有没有这样的MagicFunc这将使以下程序输出字符串my info来自底层 Foo 实例 package main import fmt type Foo struct A string fun
  • 共享来自单独命令/进程的属性

    我提供带有多个命令和子命令的命令行工具 我使用cobra https github com spf13 cobra命令行 我有两个单独的命令首先是前提条件e 给其他人 例如第一个命令是通过创建临时文件夹并验证某些文件来首选环境 第二个命令应
  • 为什么我的 SQL 占位符没有被替换(使用 Go pq)?

    根据文档 我正在这样做 var thingname string asdf var id int err database QueryRow SELECT id from things where thing thingname Scan
  • 如何将未知字段类型的数据解组为 JSON

    我有这些 结构 type Results struct Gender string json gender Name struct First string json first Last string json last json nam
  • 投射回更专业的界面

    我正在用 Go 编写一个游戏 在 C 中 我将所有实体类存储在 BaseEntity 类的数组中 如果一个实体需要在世界中移动 那么它将是一个从 BaseEntity 派生的 PhysEntity 但添加了方法 我尝试模仿这是 go pac
  • 在函数中将通道作为参数传递的不同方法

    我正在阅读一些Go代码 并说了几种传递Go通道的不同方法 也许它们是相同的 但我想知道是否有任何区别 因为我无法在线找到文档 1 func serve ch lt chan interface do stuff 2 func serve c
  • Swift:覆盖子类内的类型别名

    所以我正在考虑在我的项目中使用自定义模式 但我无法让它发挥作用 主要思想是改变typealias在每个子类上访问子类特定的接口 protocol InstanceInterface class typealias Interface var
  • 如何在golang模板上打印JSON?

    我需要在客户端有一个对象 所以我使用 json marshal 将其转换为 JSON 并将其打印到模板中 该对象被打印为转义 JSON 字符串 我期待它是var arr o1 o2 但它是var arr o1 o2 我知道我可以在客户端进行
  • 在 IntelliJ IDEA 中运行。多个文件和错误未定义:数据

    我想使用 IntelliJ IDE 社区版编写代码GO Go语言 我安装了正确的插件 并安装了构建应用程序所需的所有工具 我的应用程序包含以下两个文件 每个都在目录中 事件服务器 Main go Data go 如果我想使用 Run Ctl
  • 在golang中获取TTFB(第一个字节的时间)值

    我正在尝试获取 TTFB 值和 Connect 值 c exec Command curl w Connect time connect TTFB time starttransfer Total time time total o dev
  • 通用特征的隐式转换

    我正在实现一个数据结构 并希望用户能够使用任何类型作为密钥 只要他提供一个合适的密钥类型来包装它 我有这个关键类型的特质 这个想法是进行从基类型到键类型的隐式转换 反之亦然 实际上 只使用基类型 该特征看起来像这样 trait Key T
  • 非严格的多接口类型参数约束?

    对不起 如果这是一个骗局 但我似乎无法获得正确的关键字组合来过滤各种类型约束和泛型问题 因为有很多 我有两个接口 我们称它们为IOnline and IOffline 它们密切相关 因为它们描述了几乎相同的合约 但它们之间的主要区别之一是使
  • TypeScript 中泛型的不安全隐式转换

    TypeScript 编译器tsc编译以下代码 即使使用 strict旗帜 然而 该代码包含一个基本错误 而在 Java 或 C 等语言中可以避免这种错误 interface IBox
  • 编写每个处理程序中间件

    我希望从处理程序中提取一些重复的逻辑 并将其放入一些每个处理程序的中间件中 特别是 CSRF 检查 检查现有会话值 即身份验证或预览页面 等 我读了关于此的几篇文章 http justinas org writing http middle
  • 将类型传递给通用 Swift 扩展,或者理想情况下推断它

    说你有 class Fancy UIView 你想找到所有兄弟姐妹Fancy意见 没问题 https stackoverflow com q 37232743 294884 for v UIView in superview subview
  • TObjectList.Contains 导致 Delphi 2009 中的访问冲突

    在 Delphi 2009 中 到目前为止 我在泛型方面没有遇到大问题 使用 Generics Collections 列表 没有特殊的泛型功能 现在我发现这段代码会在访问的行中导致AVMyList Contains 如果我声明 TMyLi
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary

随机推荐

  • 反序列化时二进制流“0”不包含有效的 BinaryHeader 错误

    在过去两天寻找这个问题的答案后 我希望这里有人能提供帮助 我使用 VS2012 用 c 编写了一个程序 该程序使用 BinaryFormatter 保存用户的项目数据 以将可序列化的类序列化为 Stream 然后再将其保存到文件中 该程序已
  • JavaScript 数组上的 getter/setter?

    有没有办法在数组上获取 设置行为 我想象这样的事情 var arr one two three var arr new Array for var i 0 i lt arr length i arr i defineGetter value
  • 如何从 ngModel 渲染 HTML 标签?

    我使用 AngularJS 将 JS 变量绑定到我的 HTML 内容 它工作得很好 JS var app angular module Tabs controller TabsController scope function scope
  • 如何以唯一的顺序对数组进行排序

    给定一个数组 var myList Normal Urgent Alert Casual Follow up 我想以下拉菜单的形式输出这个列表 我想 Urgent 首先出现 然后是 Alert 其余的应按字母顺序排序 我知道我可以按字母顺序
  • 如何在 Hapi 中获取请求的完整 URL

    在我的 hapijs 应用程序中 给定Request object http hapijs com api request object 如何找到原始的 未解析的 未修改的 URL function getRequestUrl reques
  • 您使用 Matlab/F#/R 进行数据分析和建模算法的经验

    我已经使用 F 一段时间来对算法进行建模 然后再用 C 进行编码 之后还使用它来检查 C 代码的结果 以及对照实际记录的数据 对于建模方面 它非常方便 但对于 数据混搭 之类的东西 从 CSV 和其他来源提取数据 生成统计数据 绘制图表等
  • 无法将 RoboMongo 与 Amazon 实例连接

    我无法将 RoboMongo 与 Amazon 实例连接 试过这个http blog mongohq com robomongo your next shell http blog mongohq com robomongo your ne
  • Django ModelForm 有一个隐藏的输入

    所以我有我的 TagStatus 模型 我正在尝试为其制作一个 ModelForm 但是 我的表单要求用 tag name 填充隐藏输入 我一直在浏览文档 但不知道如何使标签字段成为隐藏输入 也许 ModelForm 不是正确的选择 模型
  • 如何使用 Android ZoomButtonsController?

    好吧 我已经无计可施了 我不知道该怎么做使用 android widget ZoomButtonsController http developer android com reference android widget ZoomButt
  • 为什么我的 base64 编码的 png 在我的 svg 中不可见?

    我想将 png 转换为 base64 并将编码后的字符串插入 svg 中 fIm open name png rb dataIm fIm read encode base64 replace n baseIm
  • Java 语言规范中是否曾经发生过“重大变化”?

    除了引入 assert 关键字这一可能广为人知的例外情况之外 Java 语言规范是否曾发生过变化 导致旧代码不再与 JDK 的较新源代码级别兼容 到目前为止的总结 非常感谢您的评论 当升级到更高版本时 如果代码使用使用 Java 语言规范
  • Android:单击按钮时转到 HTTP URL

    我想通过单击 Android 应用程序中的按钮来访问网页 比如说 我有一个名为 Google 的按钮 当用户单击该按钮时 我希望 google com 在屏幕上打开 这是如何实现的 另外 当用户使用完 Google 后 有没有办法可以重新获
  • python:动态获取字典中的子字典?

    假设我想编写一个函数 它将从字典返回任意值 例如 mydict foo bar baz 如果不存在则返回空字符串 不过 我不知道是否mydict foo 必然存在 更不用说mydict foo bar baz 我想做这样的事情 safe n
  • 在 Safari 中使用 location.hash 滚动页面

    我有一个论坛页面 在当前选定的消息下方显示消息的树视图 当您单击树中的消息时 新消息正文将加载到div使用 AJAX 靠近页面顶部 然后运行以下代码 window location hash page top 当然 page top 是页面
  • LLVM 的整数类型

    LLVM语言将整数类型指定为iN 其中N是整数的位宽 范围从1到2 23 1 根据 http llvm org docs LangRef html integer type http llvm org docs LangRef html i
  • 如何处理所有可用 iPhone 分辨率上的图像比例?

    什么尺寸最适合用于图像 background png 电子邮件受保护 cdn cgi l email protection and 电子邮件受保护 cdn cgi l email protection例如 如果我们想使用此图像来覆盖 iPh
  • Objective-c 类运行时定义

    是否可以在 Objective C 中在运行时定义类 例如 我收到一个 XML 文件 该文件定义了一个对象并创建它并在运行时使用它 是的 检查一下这个代码片段 我在这里创建了一个类 仅使用 C 方法和一个协议定义 为了在进行消息调用时简单起
  • Android Google Maps Api V2,获取当前地图中心的坐标

    我正在使用 Android Google Maps Api V2 不是 MapView 或 MapActivity 并且很难获取地图中心的坐标 我正在考虑使用 Override public void onCameraChange Came
  • 如何使用 NSAttributedString w/ UILabel 进行描边和填充

    两者都可以申请吗stroke and fill与NSAttributedString and a UILabel 是的 关键是要申请Negative的价值NSStrokeWidthAttributeName如果该值为正数 您将只能看到描边而
  • 是否可以从分配给什么返回值来推断类型参数?

    假设我写了两个这样的函数 func ToInterfaceSlice T any s T interface res make interface len s for i v range s res i v return res func