如何在F#中为已有值执行类型转换并添加度量单位?
为C#来源数值添加F#度量单位的正确实现
项目依赖不可修改的C#代码,需将其中的int值转换为带度量单位的类型(如米、角度),同时保证类型安全(不同单位/无单位值不可相加)。
依赖的C#代码
namespace test { public class Polygon { public int angle = 3; public int length = 1; } }
错误尝试的问题根源
之前的写法混淆了类型别名与度量单位的应用方式:
float<m>是带度量标记的基本类型,不是可实例化的类,不能用a x或float<m> x这类构造式写法float与float<m>是完全独立的类型,无继承关系,无法通过upcast/downcast转换
正确实现方式
1. 定义度量单位
[<Measure>] type m // 米 [<Measure>] type deg // 角度(可选,用于angle字段)
2. 数值转换与度量标记
对于int转带度量的float,有两种简洁方式:
open test let x : int = 1 // 方式1:乘以带度量的单位值(最直观) let y : float<m> = float x * 1.0<m> // 方式2:使用F#语言原语 let z : float<m> = LanguagePrimitives.FloatWithMeasure (float x)
如果需要带度量的int类型:
let x : int = 1 let y : int<m> = x * 1<m> // 或用语言原语 let z : int<m> = LanguagePrimitives.Int32WithMeasure x
3. 实际用例的正确代码
open test [<Measure>] type m let getLength (shape : test.Polygon) : float<m> = // 将int转换为float后,标记度量单位 float shape.length * 1.0<m> let getSides (shape : test.Polygon) : float = float shape.angle // 保持无单位 let usecase (shape : test.Polygon) = let fancySide = getLength shape let fancySides = getSides shape fancySide + fancySides // 编译报错(符合预期:float<m>与float类型不兼容)
内容的提问来源于stack exchange,提问作者UpTide
相关产品推荐
相关产品推荐

