【问题标题】:Scala: Combine two methods, one returning a List, other a Set into one method using GenericsScala:使用泛型组合两种方法,一种返回 List,另一种 Set 为一种方法
【发布时间】:2013-11-29 00:42:39
【问题描述】:

这里是菜鸟。如何创建一个可以用来代替以下 2 种方法的方法?

 def makeListSavingsAccounts( numSavAccts: Int ): List[ SavingsAccount] = {
    var saList: List[ BankAccount ] = List.empty 
    for ( saIDX <- 1 to numSavAccts ) saList :+= new SavingsAccount( 5000 )
    saList
  } 



  def makeSetSavingsAccounts( numSavAccts: Int ): Set[ SavingsAccount] = {
    var saSet: Set[ BankAccount ] = Set.empty 
    for ( saIDX <- 1 to numSavAccts ) saSet += new SavingsAccount( 5000 )
    saSet
  }   

类似的东西????

  def makeCollectionSavingsAccounts[T <: ???[ SavingsAccount ]] ( numSavAccts:Int ): T = {
    var saColl: T = ???.empty 

    for ( saIDX <- 1 to numSavAccts ) saColl  ?????? new SavingsAccount( 5000 )
    saColl
  }

感谢您分享您丰富的 Scala 知识...

【问题讨论】:

  • 为了简单起见:为什么不在第二种方法中只调用列表中的 toSet 方法?
  • 感谢您的建议。我想我也可以先调用 toList 。我只是想了解如何使用泛型来实现这一点。

标签: scala scala-collections


【解决方案1】:

这是遵循 Scala 集合库的方式。所以我相信以下方式是原生的。

scala> def makeSavingAccounts[T[_]](count:Int)(implicit cbf: scala.collection.generic.CanBuildFrom[T[_], BankAccount, T[BankAccount]]) = {
        val builder = cbf()
        builder.sizeHint(count)
        for(i <- 1 to count) builder += SavingsAccount(5000)
        builder.result
      }

scala> makeSavingAccounts[List](3)
res0: List[BankAccount] = List(SavingsAccount(5000), SavingsAccount(5000), SavingsAccount(5000))

scala> makeSavingAccounts[Set](3)
res2: Set[BankAccount] = Set(SavingsAccount(5000))

【讨论】:

  • 可以将CanBuildFrom的类型参数化改为CanBuildFrom[Nothing, BankAccount, T[BankAccount]]。即使在调用makeSavingAccounts 方法时省略类型参数,它也能找到CanBuildFrom 实例。
  • 我不得不使用'new SavingsAccount(5000)' 相当的签名!看来我要学的东西很多。谢谢大家。 Knut 的建议也有效。猜猜我认为它会更简单:(
【解决方案2】:

没有任何神奇的东西,比如 can-build-from 和 builders:

def makeListSavingsAccounts(accsNum: Int ): List[ SavingsAccount] = {
    val accs = for (saIDX <- 1 to accsNum) yield new SavingsAccount( 5000)
    accs.toList
}

def makeSetSavingsAccounts(accsNum: Int): Set[SavingsAccount] = 
    makeListSavingsAccounts(accsNum).toSet

附: makeListSavingsAccounts 的替代实现是 List.fill(accsNum)(new SavingsAccount( 5000))

【讨论】:

    猜你喜欢
    • 2017-10-30
    • 1970-01-01
    • 2011-10-06
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多