我正在寻找一种方法,让类的行为就像case类一样,但是它们会自动散列为hash.
实现整数列表的一种方法是:
import scala.collection.mutable.{Map=>MutableMap}
sealed abstract class List
class Cons(val head: Int, val tail: List) extends List
case object Nil extends List
object Cons {
val cache : MutableMap[(Int,List),Cons] = MutableMap.empty
def apply(head : Int, tail : List) = cache.getOrElse((head,tail), {
val newCons = new Cons(head, tail)
cache((head,tail)) = newCons
newCons
})
def unapply(lst : List) : Option[(Int,List)] = {
if (lst != null && lst.isInstanceOf[Cons]) {
val asCons = lst.asInstanceOf[Cons]
Some((asCons.head, asCons.tail))
} else None
}
} …Run Code Online (Sandbox Code Playgroud) 假设我想编写一个case类Stepper,如下所示:
case class Stepper(step: Int) {def apply(x: Int) = x + step}
Run Code Online (Sandbox Code Playgroud)
它带有一个很好的toString实现:
scala> Stepper(42).toString
res0: String = Stepper(42)
Run Code Online (Sandbox Code Playgroud)
但它不是真正的功能:
scala> Some(2) map Stepper(2)
<console>:10: error: type mismatch;
found : Stepper
required: Int => ?
Some(2) map Stepper(2)
Run Code Online (Sandbox Code Playgroud)
解决方法是实现Function特性......
case class Stepper(step: Int) extends (Int => Int) {def apply(x: Int) = x + step}
Run Code Online (Sandbox Code Playgroud)
但是,我不能再免费获得一个很好的toString实现了:
scala> Stepper(42).toString
res2: java.lang.String = <function1>
Run Code Online (Sandbox Code Playgroud)
然后,问题是:我可以充分利用这两个世界吗?有没有一个解决方案,我有漂亮的toString自由执行和特点的实现Function.换句话说,有没有办法以最终应用case class语法糖的方式应用线性化?
定义空特性测试:
trait Test
Run Code Online (Sandbox Code Playgroud)
复合型中使用的是什么:
scala> val a : Int with Test = 10.asInstanceOf[Int with Test]
a: Int with Test = 10
Run Code Online (Sandbox Code Playgroud)
和带有复合类型参数的case类(如Unboxed Tagged Type):
scala> case class Foo(a: Int with Test)
error: type mismatch;
found : Double
required: AnyRef
Note: an implicit exists from scala.Double => java.lang.Double, but
methods inherited from Object are rendered ambiguous. This is to avoid
a blanket implicit which would convert any scala.Double to any AnyRef.
You may wish to use a type ascription: `x: java.lang.Double`. …Run Code Online (Sandbox Code Playgroud) 在Scala成为一个参数apply()之前,是否有一种方法可以修改传递给单参数案例类构造函数/ 方法的参数val?例如
case class AbsVal private(aVal: Double)
object AbsVal {
def apply(aVal: Double): AbsVal = AbsVal(Math.abs(aVal)) // doesn't compile
}
Run Code Online (Sandbox Code Playgroud)
当然,这对于重载定义的模糊引用是失败的.我想也许我可以使用命名参数(以及构造函数vs的不同参数名称apply())来欺骗它,但这也不起作用.
当然,而不是apply()我可以拥有私有构造函数和工厂方法,但是不得不乱丢代码AbsVal.make(x)而烦人AbsVal(x).
是否可以在案例类中实现双向树.这看起来应该很容易,但我很难过
case class Node(name:String, parent:Option[Node], children:List[Node])
Run Code Online (Sandbox Code Playgroud)
我想添加一个孩子(并获得一个新的根) - 类似的东西
def addChild(n:String):Node = {
Node(name, parent, Node(n, Some(this), Nil)::children)
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为孩子中的"父母"将不再引用将孩子列为孩子的节点.这是可能的不可变列表和案例类?
根据下面给出的答案
case class Node(name: String, parent: () => Option[Node], children: List[Node]) {
def makeChild(name: String) = {
lazy val newParent:Node = Node(this.name, this.parent, kid :: this.children)
lazy val kid:Node = Node(name, () => Some(newParent), Nil)
newParent
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个简单的类层次结构,它表示一个类似于图形的结构,其中有几个不同类型的顶点使用case类实现:
sealed trait Node
sealed abstract case class Vertex extends Node
case class Arc extends Node
case class VertexType1 (val a:Int) extends Vertex
case class VertexType2 (val b:Int) extends Vertex
Run Code Online (Sandbox Code Playgroud)
这允许我写这样的匹配块:
def test (x: Node) = x match {
case _ : Arc => "got arc"
case _ : Vertex => "got vertex"
}
Run Code Online (Sandbox Code Playgroud)
或者像这样:
def test (x: Node) = x match {
case _ : Arc => "got arc"
case c : Vertex => c match {
case _ …Run Code Online (Sandbox Code Playgroud) 首先介绍一下上下文:我在Scala(第一人称射击游戏)中编写客户端/服务器游戏,其中客户端需要每秒向服务器发送几十次运动意图并且服务器将实体状态发送回来,实时也是如此.在客户端(用于图形流动性)和服务器端使用JBullet对这些实体进行物理模拟.每当客户端从服务器接收更新时,它都会将其本地状态替换为服务器发送的状态.当然,在给定时刻,同一服务器上可能有许多客户端.简而言之,在这种应用中,通信经常发生,带有小数据包.
目前,我正在使用Akka的演员天真地通过网络将Scala案例类发送到服务器并返回.这是一个例子:
sealed trait PlayerMessage
case class PlayerMove(dir: Vector3, run: Boolean) extends PlayerMessage
// more case classes...
Run Code Online (Sandbox Code Playgroud)
然后在客户端:
server ! PlayerMove(dir, run)
Run Code Online (Sandbox Code Playgroud)
在服务器上:
def receive = {
case pm: PlayerMessage => pm match {
case p @ PlayerMove(dir, run) =>
// Move the player
world.playerMove(dir,run)
// More case tests..
}
// Send back entity states (this in fact occurs elsewhere, asynchronously)
world.entities.foreach(ent => client ! ent.state()))
// More message testing ...
case _ => // ignore
}
Run Code Online (Sandbox Code Playgroud)
ent.state返回EntityState的位置:
case class …Run Code Online (Sandbox Code Playgroud) 考虑定义两个属性的抽象类
abstract class A {
def a: Int
def b: Int
// real A has additional members
}
Run Code Online (Sandbox Code Playgroud)
这是各种案例类的基类,如
case class Foo(a: Int, b: Int) extends A
case class Bar(a: Int, b: Int) extends A
// and many more
Run Code Online (Sandbox Code Playgroud)
目标:我最终希望能够以两种方式创建上述案例类的实例,即
val b1 = Bar(1, 2)
val b2 = Bar(1) has 2
assert(b1 == b2) // must hold
Run Code Online (Sandbox Code Playgroud)
方法:因此,定义一个帮助类来定义has并允许我部分构造As 似乎是合理的
case class PartialA(f: Int => A) {
def has(b: Int) = f(b)
}
Run Code Online (Sandbox Code Playgroud)
问题:当前机制不允许调用, …
假设您有类似以下的案例类
case class Test1(a:String,b:Int,c:Char)
case class Test2(a:String,b:Int)
Run Code Online (Sandbox Code Playgroud)
并使用以下变量实例化类
val test1 = Test1("first",2,'3')
val test2 = Test2("1st",20)
Run Code Online (Sandbox Code Playgroud)
有没有办法使用该.copy方法(或其他方法),将Test2中的变量应用于Test1,如
val test3 = test1.copy(test2) //Note this isn't valid scala code
// Result should be ("1st",20,'3')
Run Code Online (Sandbox Code Playgroud)
如果在纯scala中这是不可能的,那么它将如何在Shapeless 1/2中完成(当前代码在Shapeless 1中,但我们计划在某个时间点升级到Shapeless 2)
我的用例有类似的案例类
case class Address(name:String,pincode:String){
override def toString =name +"=" +pincode
}
case class Department(name:String){
override def toString =name
}
case class emp(address:Address,department:Department)
Run Code Online (Sandbox Code Playgroud)
我想创建一个类似下面的DSL.任何人都可以分享有关如何创建DSL的链接以及实现以下内容的任何建议.
emp.withAddress("abc","12222").withDepartment("HR")
Run Code Online (Sandbox Code Playgroud)
更新: 实际用例类可能有更多字段接近20.我想避免代码的减少
case-class ×10
scala ×10
dsl ×2
actor ×1
akka ×1
extractor ×1
inheritance ×1
object ×1
shapeless ×1
traits ×1