【问题标题】:Passing parameters to a trait将参数传递给特征
【发布时间】:2016-08-17 10:23:23
【问题描述】:

我想为国际象棋游戏建模。 为此,我想创建一个抽象类Piece,它将玩家和位置作为参数。从此,我想扩展到其他类,例如Pawn

trait Piece(player: Int, pos: Pos) = {

  def spaces(destination: Pos): List[Pos]

}

case class Pawn extends Piece = {
//some other code
}

但是,我认为我不允许将参数传递给特征,例如 trait Piece(player: Int, pos: Pos)

那么我怎样才能拥有一个包含字段的抽象类Piece

【问题讨论】:

标签: scala


【解决方案1】:

你可以使用抽象类

abstract class Piece(player: Int, pos: Pos) {
  ...
}

case class Pawn(player: Int, pos: Pos) extends Piece(player, pos)

或者(可能更好)您在特征中抽象地定义这些成员

trait Piece {
  def player: Int
  def pos: Pos
  ...
}

case class Pawn(player: Int, pos: Pos) extends Piece

【讨论】:

  • 第二个具有特征的解决方案:在这方面使用 cass 类的机制(隐式 getter 方法),聪明!谢谢
  • 和 Scala 3.0 带来了我现在的“参数化特征”
【解决方案2】:

Dotty allows traits to have parameters, just like classes have parameters.

trait Greeting(val name: String) {
  def msg = s"How are you, $name"
}

class C extends Greeting("Bob") {
  println(msg)
}

【讨论】:

    【解决方案3】:

    我对我的用例接受的答案不满意,所以我做了以下事情。请注意,对于这种相同的方法,您有两种可能性:

    trait Piece {
       // these can be referred to within this trait to implement reusable code
       val player: Int 
       val pos: Pos
    
       def spaces(destination: Pos): List[Pos] = {
         // use player and pos at will e.g.
         List(pos, destination)  
       }
    }
    
    case class Pawn(playerArg: Int, posArg: Pos) extends Piece = {
       // now override those with whatever you like
       override val player: Int = playerArg 
       override val pos: Pos = posArg
    
       //some other code
    }
    

    第二种选择是使用和覆盖方法,例如def getPlayer: Int.

    另一种可能性是在需要访问这些属性的 trait 方法上使用 implicit,但我不喜欢这种方法。

    也就是说,显然他们一直在考虑SIP-25 Trait Parameters

    【讨论】:

      猜你喜欢
      • 2015-06-07
      • 2020-02-27
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 2023-04-04
      • 2023-04-01
      相关资源
      最近更新 更多