首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在F#中不能扩展操作符吗?

在F#中不能扩展操作符吗?
EN

Stack Overflow用户
提问于 2011-11-29 10:59:10
回答 2查看 486关注 0票数 3
代码语言:javascript
复制
module FSharp=
let Point2d (x,y)= Point2d(x,y)
let Point3d (x,y,z)= Point3d(x,y,z)
type NXOpen.Point3d with
    static member ( * ) (p:Point3d,t:float)= Point3d(p.X*t,p.Y*t,p.Z*t)
    static member ( * ) (t:float,p:Point3d)= Point3d(p.X*t,p.Y*t,p.Z*t)
    static member (+) (p:Point3d,t:float)= Point3d(p.X+t,p.Y+t,p.Z+t)
    static member (+) (t:float,p:Point3d)= Point3d(p.X+t,p.Y+t,p.Z+t)
    static member (+) (p:Point3d,t:Point3d)= Point3d(p.X+t.X,p.Y+t.Y,p.Z+t.Z)

let a=Point3d (1.,2.,3.)
let b=1.0
let c=a * b//error

错误15:类型'float‘与类型不匹配

‘E:\Work\extension-RW\VS\extension\NXOpen.Extension.FSharp\Module1.fs’Point3d 18 13 NXOpen.Extension.FSharp

我想扩展Point3d方法,一些新的运算符。但它不会过去。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-30 13:45:38

事实上,这是可能的。有一种方法可以使用one和only和little known ternary operator ?<-扩展二进制运算符。所以,在你的例子中,你可以试试这个:

代码语言:javascript
复制
type SumPoint3d = SumPoint3d with
    static member        (?<-) (p:Point3d, SumPoint3d, t        ) = Point3d(p.X + t  , p.Y + t  , p.Z + t  )
    static member        (?<-) (t        , SumPoint3d, p:Point3d) = Point3d(p.X + t  , p.Y + t  , p.Z + t  )
    static member        (?<-) (p:Point3d, SumPoint3d, t:Point3d) = Point3d(p.X + t.X, p.Y + t.Y, p.Z + t.Z)
    static member inline (?<-) (a        , SumPoint3d, b        ) = a + b

type ProdPoint3d = ProdPoint3d with    
    static member        (?<-) (p:Point3d, ProdPoint3d, t        ) = Point3d(p.X * t, p.Y * t, p.Z * t)
    static member        (?<-) (t        , ProdPoint3d, p:Point3d) = Point3d(p.X * t, p.Y * t, p.Z * t)
    static member inline (?<-) (a        , ProdPoint3d, b        ) = a * b

let inline ( + ) a b =  a ? (SumPoint3d ) <- b
let inline ( * ) a b =  a ? (ProdPoint3d) <- b

let a=Point3d (1.,2.,3.) 
let b=1.0

现在你可以试着:

代码语言:javascript
复制
> let c=a * b ;;
val c : Point3d = Point3d (1.0,2.0,3.0)

>  2 * 3 ;;
val it : int = 6
票数 3
EN

Stack Overflow用户

发布于 2011-11-29 11:54:57

如果Point3d类型是在不能修改的单独程序集中声明的,那么(不幸的是)无法实现标准运算符(如+* )的新重载。问题中的代码添加操作符作为扩展方法,但是F#编译器在查找重载运算符时不搜索扩展方法。

如果您不能修改库,那么您可以做三件事:

  • Point3d创建一个包装器,该包装器存储Point3d值并实现所有运算符。

(但这可能是相当inefficient)

  • Define的新运营商,不会与内置运营商发生冲突。例如,您可以使用+$$+从左和右用标量进行乘法。要声明这样的运算符,您可以这样写:

设(+$) (f:float) (a:Point3d) = (...)

  • Implement您自己的Point3d类型,它完成所有工作,可能使用一个转换函数,在需要调用库时将其转换为Point3d

很难说哪种选择是最好的--第二种方法可能是最有效的,但它会使代码看起来更加丑陋。根据您的场景,选项1或3也可能有效。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8309620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档