如何根据Scala中的条件动态返回对象?

时间:2019-02-15 13:35:53

标签: scala

我已经实现了五到六个聚类算法。我想返回聚类算法的对象,因为用户在“ cluster”方法中指定了它的名称。例如:-

  val kmeans= data.cluster(clusteringAlgo.Kmeans)

当集群方法用Kmeans调用并与Kmeans匹配时,它应返回kmeans实例。

  def cluster(firstName: ClusteringAlgorithm.Value):???= {  
  algoName = firstName.toString()
  if (ClusteringAlgorithm.KMeans.toString() == algoName) {
    val kmeans = new Kmeans(input)
    Kmeans
  } 
  else if (ClusteringAlgorithm.DBSCAN.toString() == algoName) {
    val dbscan = new DBSCAN(input, epsilon, maxPoints)
    dbscan
  }
  ......

由于每个条件(kmeans,dbscan等)的返回类型都不同,因此我面临返回类型的困难。应该在???在代码中。我们怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

有一种可能性(使用高阶函数):

提供带有构造函数的Map:

val cluster = Map(ClusteringAlgorithm.KMeans -> createKMeans,
ClusteringAlgorithm.DBSCAN -> createDBScan
) 

def createKMeans() = new Kmeans(input)
def createDBScan() = new DBSCAN(input, epsilon, maxPoints)

用法:

val kmeans = cluster(ClusteringAlgorithm.KMeans)()

模式匹配

def cluster(name: ClusteringAlgorithm.Value) = name match {
 case ClusteringAlgorithm.KMeans => new Kmeans(input)
 case ClusteringAlgorithm.DBSCAN => new DBSCAN(input, epsilon, maxPoints)
}

用法:

val kmeans = cluster(ClusteringAlgorithm.KMeans)

该功能也可以参数化,例如

def cluster[A](name: ClusteringAlgorithm.Value): A = name match {
 case ClusteringAlgorithm.KMeans => new Kmeans(input)
 case ClusteringAlgorithm.DBSCAN => new DBSCAN(input, epsilon, maxPoints)
}

val kmeans = cluster[Kmeans](ClusteringAlgorithm.KMeans)

答案 1 :(得分:1)

除了@pme的答案之外的另一种选择

      trait ClusterAlgo {
        //This is just a marker trait/interface. no implementation is required.

      }

      class Kmeans extends ClusterAlgo {
        // your implementation goes here
      }

      class DBSCAN extends ClusterAlgo {
        // your implementation goes here
      }

      class SomeOtherAlgo extends ClusterAlgo {
        // your implementation goes here
      }

      def cluster(firstName: String): ClusterAlgo = {

        if (firstName.equalsIgnoreCase("kmeans")) {
          new Kmeans
        }
        else if (firstName.equalsIgnoreCase("dbscan")) {
          new DBSCAN()
        }
        else {
          new SomeOtherAlgo
        }

      }

//  This is a piece of code at caller. 
  println(cluster("kmeans").isInstanceOf[Kmeans])