scala 将参数传递给特征

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38993974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 08:33:47  来源:igfitidea点击:

Passing parameters to a trait

scala

提问by octavian

I want to model the game of chess. For that, I want to make an abstract class, Piecewhich takes a player and a position as arguments. From that, I want to extend to other classes such as Pawn:

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

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

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

}

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

However, I think I'm not allowed to pass parameters to a trait, like this trait Piece(player: Int, pos: Pos).

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

So how can I have an abstract class Piecethat has fields?

那么我怎样才能拥有一个Piece具有字段的抽象类呢?

回答by 0__

You could use an abstract class

你可以使用抽象类

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

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

Or (probably better) you define those members abstractly in a trait

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

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

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

回答by AZ_

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

Dotty 允许 trait 有参数,就像类有参数一样。

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

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

回答by SkyWalker

I wasn't happy with the accepted answer for my use-case so I did the following. Note that you have two possibilities here for this same approach:

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

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
}

The second alternative is to use and override methods instead e.g. def getPlayer: Int.

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

Yet another possibility is to use impliciton the trait methods that would require accessing those attributes but I'm not a big fan of this approach.

另一种可能性是implicit在需要访问这些属性的特征方法上使用,但我不是这种方法的忠实粉丝。

That said, apparently they have been thinking about it SIP-25 Trait Parameters.

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