ToString() 与字符串运算符的类型推断

2024-04-04

注:这个问题和我的有些关系前一个 https://stackoverflow.com/questions/41347374/tostring-throws-nullreferenceexception-for-unit-value,但实际上从不同的角度触及了这个问题

考虑以下片段:

let toStr a = a.ToString()
let strOp a = string a

let intToStr = 5 |> toStr
let floatToStr = 5.0 |> toStr

let intStrOp = 5 |> strOp
let floatStrOp = 5.0 |> strOp //type inference error

虽然strOp函数使用看起来更优雅的解决方案,并且也能够将单位值转换为字符串,它似乎不是真正通用的,因为它的类型在第一次使用期间受到限制(即使推断的类型是obj -> string, not 'a -> string)

为什么字符串运算符不能以如此通用的方式工作?或者我做错了什么?


不同之处在于string使用静态成员约束(参见定义 https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/prim-types.fs#L4485) while ToString是可用于任何对象的普通方法,因此编译器将其视为ToString作为通用代码调用,不会以任何方式限制实例类型。

静态约束和(非静态)泛型在(否则不受约束)中使用时以不同的方式工作let绑定函数:

  • 对于通用代码,编译器传播通用性并使let-bound 函数你也写了通用的。

  • 对于静态成员约束,编译器根据第一次使用来专门化代码。正如评论中提到的,您可以通过使用来避免这种情况inline,它允许基于静态成员的通用性以与序数通用代码相同的方式传播。

我认为唯一的原因是string函数使用静态解析类型约束的原因是它允许它像普通函数一样专门化ToString调用原始类型,但仍然处理null对象的自定义方式的值 -toStr null抛出异常但是strOp null返回一个空字符串!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ToString() 与字符串运算符的类型推断 的相关文章

随机推荐