如何在Scala中作为班级成员发起?

时间:2019-02-18 06:49:48

标签: scala mleap

我有一个随机数类,它会生成随机数。但是我希望它作为类成员启动,这样我们就不必在每次调用时都重新生成。下面是当前的代码。

import ml.combust.mleap.core.Model
import ml.combust.mleap.core.types._

case class RandomNumberModel() extends Model{

  def apply(input: String):  Double  = {
    val rnd = scala.util.Random
    return rnd.nextFloat
  }

  override def inputSchema: StructType = StructType("input" -> ScalarType.String).get

  override def outputSchema: StructType = StructType("output" -> ScalarType.Double ).get

}

我是scala的新手,需要建议我必须在这里做哪些更改?

3 个答案:

答案 0 :(得分:3)

尝试

case class RandomNumberModel() extends Model {
  private val rnd = scala.util.Random

  def apply(input: String): Double = rnd.nextFloat

  override def inputSchema: StructType = StructType("input" -> ScalarType.String).get

  override def outputSchema: StructType = StructType("output" -> ScalarType.Double ).get

}

答案 1 :(得分:1)

这主要是对您自己答案的回答,但不适合评论。

  1. Scala具有内置的和线程安全的替代方法,可替代您对var _instancedef instancelazy val所做的操作。使用它,我们得到

    object RandomNumberModel {
      // private is still visible in the companion class
      private lazy val instance : Random = scala.util.Random
    }
    
    // in the class:
    val inst = RandomNumberModel.instance
    
  2. 由于在使用RandomNumberModel时始终需要初始化实例,因此在这种情况下,实际上lazy并没有带来任何好处,只有很小的开销。伴随对象中的非懒惰val仅在加载类时才初始化,例如创建类的第一个实例时。因此,只需private val instance : Random = scala.util.Random

  3. 您不需要存储始终指向类中同一实例的引用,这只会浪费内存。最好直接使用RandomNumberModel.instance

    case class RandomNumberModel() extends Model{
        def apply(input: String):  Double  = {
            RandomNumberModel.instance.nextFloat // why not nextDouble?
        }
    
        ...
    }
    
  4. 您有多个使用相同Random的模型。如果您的程序曾经有多个线程操纵模型,请注意

      

    Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance.

    如果您使用ThreadLocalRandom,它将自行处理初始化:

    case class RandomNumberModel() extends Model{
        def apply(input: String):  Double  = {
             ThreadLocalRandom.current.nextFloat
        }
    
        ...
    }
    
    // object RandomNumberModel is gone
    
  5. 您是否希望所有RandomNumberModel都相等?如果没有,请不要设置为case class

答案 2 :(得分:0)

我尝试了如下操作,这样可以正常工作,或者在这里我做错了什么:

use SSH tunnel