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

用于Scala中编译时对象创建的语法糖

发布时间:2020-12-16 10:01:18 所属栏目:安全 来源:网络整理
导读:可以说我有 trait fooTrait[T] { def fooFn(x: T,y: T) : T } 我希望用户能够使用自己定义的fooFn主体快速声明fooTrait的新实例.理想情况下,我想要类似的东西 val myFoo : fooTrait[T] = newFoo((x:T,y:T) = x+y) 上班.但是,我不能这样做 def newFoo[T](f: (
可以说我有

trait fooTrait[T] {
  def fooFn(x: T,y: T) : T 
}

我希望用户能够使用自己定义的fooFn主体快速声明fooTrait的新实例.理想情况下,我想要类似的东西

val myFoo : fooTrait[T] = newFoo((x:T,y:T) => x+y)

上班.但是,我不能这样做

def newFoo[T](f: (x:T,y:T) => T) = new fooTrait[T] { def fooFn(x:T,y:T):T = f(x,y); }

因为它使用闭包,因此在程序多次运行时会产生不同的对象.我真正需要的是能够获取newFoo返回的对象的classOf,然后可以在不同的机器上构造它.我该怎么办?

如果您对用例感兴趣,我正在尝试为Hadoop编写一个Scala包装器,允许您执行

IO("Data") --> ((x: Int,y: Int) => (x,x+y)) --> IO("Out")

中间的东西需要变成一个实现特定接口的类,然后可以从类名实例化到不同的机器上(执行相同的jar文件).

请注意,Scala使用转换的语法糖做正确的事(x:Int)=> x 5到Function1的一个实例.我的问题是我是否可以在不破坏Scala内部的情况下复制此内容.如果这是lisp(我已经习惯了),这将是一个简单的编译时宏……:嗅探:

解决方法

这是一个与您在问题中列出的语法相匹配并序列化/执行anon-function的版本.请注意,这会序列化Function2对象的状态,以便可以在另一台计算机上还原序列化版本.只是类名不足,如解决方案下面所示.

您应该创建自己的编码/解码功能,即使只包含您自己的Base64实现(不依赖于Sun的Hotspot).

object SHadoopImports {
    import java.io._

    implicit def functionToFooString[T](f:(T,T)=>T) = {
        val baos = new ByteArrayOutputStream()
        val oo = new ObjectOutputStream(baos)
        oo.writeObject(f)
        new sun.misc.BASE64Encoder().encode(baos.toByteArray())
    }

    implicit def stringToFun(s: String) = {
        val decoder = new sun.misc.BASE64Decoder();
        val bais = new ByteArrayInputStream(decoder.decodeBuffer(s))
        val oi = new ObjectInputStream(bais)  
        val f = oi.readObject()
        new {
            def fun[T](x:T,y:T): T = f.asInstanceOf[Function2[T,T,T]](x,y)
        }
    }
}

// I don't really know what this is supposed to do
// just supporting the given syntax
case class IO(src: String) {
    import SHadoopImports._
    def -->(s: String) = new {
        def -->(to: IO) = {
            val IO(snk) = to
            println("From: " + src)
            println("Applying (4,5): " + s.fun(4,5))
            println("To: " + snk)
        }
    }
}

object App extends Application {
  import SHadoopImports._

  IO("MySource") --> ((x:Int,y:Int)=>x+y) --> IO("MySink")
  println
  IO("Here") --> ((x:Int,y:Int)=>x*y+y) --> IO("There")
}

/*
From: MySource
Applying (4,5): 9
To: MySink

From: Here
Applying (4,5): 25
To: There
*/

为了说服自己,类名不足以在另一台机器上使用该函数,请考虑下面的代码创建100个不同的函数.计算文件系统上的类并进行比较.

object App extends Application {
  import SHadoopImports._

  for (i <- 1 to 100) {
      IO(i + ": source") --> ((x:Int,y:Int)=>(x*i)+y) --> IO("sink")
  }
}

(编辑:李大同)

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

    推荐文章
      热点阅读