加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么在Scala中可以使用这样的运算符定义?

发布时间:2020-12-16 08:51:10 所属栏目:安全 来源:网络整理
导读:我使用F#并不太了解 Scala,除了这些语言之间经常有一些相似之处.但是在Scala中查看Akka Streams实现时,我注意到使用了operator~以这种方式在F#中是不可能的(不幸的是).我不是在谈论只能在一元运算符开头的F#中使用的符号“?”,这并不重要.令我印象深刻的是定
我使用F#并不太了解 Scala,除了这些语言之间经常有一些相似之处.但是在Scala中查看Akka Streams实现时,我注意到使用了operator~>以这种方式在F#中是不可能的(不幸的是).我不是在谈论只能在一元运算符开头的F#中使用的符号“?”,这并不重要.令我印象深刻的是定义这样的图形的可能性:

in ~> f1 ~> bcast ~> f2 ~> merge ~> f3 ~> out
            bcast ~> f4 ~> merge

由于各种图形元素具有不同的类型(源,流,接收器),因此无法在F#中定义可以跨越它们的单个运算符.但我想知道为什么在Scala中这是可能的 – 这是因为Scala支持方法函数重载(而F#不支持)?

UPDATE. Fydor Soikin在F#中展示了几种重载方式,可以用来在使用F#时实现类似的语法.我试过这个,这里看起来如何:

type StreamSource<'a,'b,'c,'d>(source: Source<'a,'b>) = 
    member this.connect(flow : Flow<'a,'d>) = source.Via(flow)
    member this.connect(sink: Sink<'a,Task>) = source.To(sink)

type StreamFlow<'a,'c>(flow : Flow<'a,'c>) = 
    member this.connect(sink: Sink<'b,Task>) = flow.To(sink)

type StreamOp = StreamOp with
    static member inline ($) (StreamOp,source: Source<'a,'b>) = StreamSource source
    static member inline ($) (StreamOp,flow : Flow<'a,'c>) = StreamFlow flow

let inline connect (a: ^a) (b: ^b) = (^a : (member connect: ^b -> ^c) (a,b)) 
let inline (>~>) (a: ^a) (b: ^b) = connect (StreamOp $a) b

现在我们可以编写以下代码:

let nums = seq { 11..13 }
let source = nums |> Source.From
let sink = Sink.ForEach(fun x -> printfn "%d" x)
let flow = Flow.FromFunction(fun x -> x * 2)
let runnable = source >~> flow >~> sink

解决方法

实际上,Scala至少有四种不同的方法可以使它工作.

(1)方法重载.

def ~>(f: Flow) = ???
def ~>(s: Sink) = ???

(2)继承.

trait Streamable { 
  def ~>(s: Streamable) = ???
}
class Flow extends Streamable { ... }
class Sink extends Streamable { ... }

(3)类型和类似的通用结构.

def ~>[A: Streamable](a: A) = ???

(使用Streamable [Flow],Streamable [Sink],…提供所需功能的实例).

(4)隐含转换.

def ~>(s: Streamable) = ???

(使用隐式def flowCanStream(f:Flow):Streamable = ???等).

每个都有自己的优点和缺点,所有这些都在各种库中大量使用,尽管最后因为太容易产生意外而有些失宠.但要拥有你所描述的行为,其中任何一种都可行.

在实践中,在Akka Streams中,它实际上是我能说的1-3的混合物.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读