特别是关于模式匹配和案例类.考虑以下:
abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
object Expr {
def simplify(expr: Expr): Expr = expr match {
// Some basic simplification rules...
case UnOp("-", UnOp("-", e)) => simplify(e) // Double negation
case BinOp("+", e, Number(0)) => simplify(e) // Adding zero
case BinOp("-", e, Number(0)) => simplify(e) // Subtracting zero
case BinOp("*", e, …Run Code Online (Sandbox Code Playgroud) 定义case类时,默认的伴随对象有一个很好的curried方法来获取case类构造函数的curried版本:
scala> case class Foo(a: String, b: Int)
defined class Foo
scala> Foo.curried
res4: String => (Int => Foo) = <function1>
Run Code Online (Sandbox Code Playgroud)
但是,只要我定义了一个显式的伴随对象,这个方法就会消失:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class Foo(a: String, b: Int)
object Foo {}
// Exiting paste mode, now interpreting.
defined class Foo
defined module Foo
scala> Foo.curried
<console>:9: error: value curried is not a member of object Foo
Foo.curried
Run Code Online (Sandbox Code Playgroud)
我可以这样回来:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class …Run Code Online (Sandbox Code Playgroud) 给出以下代码:
abstract class MyTuple
...
case class MySeptet(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int, g: Int) extends MyTuple
case class MyOctet(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int, g: Int, h: Int) extends MyTuple
...
Run Code Online (Sandbox Code Playgroud)
使用生成的提取器时,是否可以跳过剩余的参数,假设它们未被使用?
例如,我不想在下面的代码片段中写下大量的下划线:
case MyOctet(a, b, _, _, _, _, _, _) => ... // uses only a and b
Run Code Online (Sandbox Code Playgroud) Scala案例类具有默认的toString函数.但是当这个case类使用现有的toString()函数扩展一个特征时,它将变得无用.我该如何防止这种情况?
我正在使用这个示例http://scala.sygneca.com/code/remoteactors来学习远程演员如何在Scala中工作(2.8.0).特别是我稍微修改了演员发送的消息如何定义如下:
sealed trait Event extends Serializable
case object Ping extends Event
case object Pong extends Event
case object Quit extends Event
Run Code Online (Sandbox Code Playgroud)
一切都按预期工作.不幸的是,如果我将事件定义为案例类而不是案例对象,如:
sealed trait Event extends Serializable
case class Ping extends Event
case class Pong extends Event
case class Quit extends Event
Run Code Online (Sandbox Code Playgroud)
我的例子停止工作.更详细地说,虽然case对象是可序列化的,但case类却不是.确实,当我尝试使用最后一次修改运行我的示例时,我得到以下异常:
scala.actors.remote.DelegateActor@148cc8c: caught java.io.NotSerializableException: scalachat.remote.Ping$
java.io.NotSerializableException: scalachat.remote.Ping$
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at scala.actors.remote.JavaSerializer.serialize(JavaSerializer.scala:46)
at scala.actors.remote.NetKernel.namedSend(NetKernel.scala:38)
at scala.actors.remote.NetKernel.forward(NetKernel.scala:71)
at scala.actors.remote.DelegateActor$$anonfun$act$1$$anonfun$apply$1.apply(Proxy.scala:182)
at scala.actors.remote.DelegateActor$$anonfun$act$1$$anonfun$apply$1.apply(Proxy.scala:123)
at scala.actors.ReactorTask.run(ReactorTask.scala:34)
at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
Run Code Online (Sandbox Code Playgroud)
是否有理由可以使case对象可序列化,而case类不能?有没有办法让我的例子使用案例类?
编辑:根据Victor的建议并由Aaron确认我将同伴对象作为消息而不是类发送.此外,使用javap检查已编译的代码,显然虽然该类是可序列化的:
public …Run Code Online (Sandbox Code Playgroud) 我有两个类PixelObject,ImageRefObject还有一些,但这里只是这两个类来简化事情.它们都是trait Object包含uid的子类.我需要通用方法,它将使用给定的new复制case类实例uid.我需要它的原因是因为我的任务是创建一个ObjectRepository类,它将保存任何子类的实例Object并使用new返回它uid.我的尝试:
trait Object {
val uid: Option[String]
}
trait UidBuilder[A <: Object] {
def withUid(uid: String): A = {
this match {
case x: PixelObject => x.copy(uid = Some(uid))
case x: ImageRefObject => x.copy(uid = Some(uid))
}
}
}
case class PixelObject(uid: Option[String], targetUrl: String) extends Object with UidBuilder[PixelObject]
case class ImageRefObject(uid: Option[String], targetUrl: String, imageUrl: String) extends Object with UidBuilder[ImageRefObject]
val pix = PixelObject(Some("oldUid"), "http://example.com")
val …Run Code Online (Sandbox Code Playgroud) 我目前正在实现一个库来序列化和反序列化XML-RPC消息.它几乎已经完成,但现在我正在尝试使用Shapeless删除当前asProduct方法的样板.我目前的代码:
trait Serializer[T] {
def serialize(value: T): NodeSeq
}
trait Deserializer[T] {
type Deserialized[T] = Validation[AnyErrors, T]
type AnyErrors = NonEmptyList[AnyError]
def deserialize(from: NodeSeq): Deserialized[T]
}
trait Datatype[T] extends Serializer[T] with Deserializer[T]
// Example of asProduct, there are 20 more methods like this, from arity 1 to 22
def asProduct2[S, T1: Datatype, T2: Datatype](apply: (T1, T2) => S)(unapply: S => Product2[T1, T2]) = new Datatype[S] {
override def serialize(value: S): NodeSeq = {
val params = …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种方法,让类的行为就像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) 在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).
在Scala中,为什么不像*类和case类(包括"空"类,如in 和case对象)那样Unit扩展Product特征?Tuplecase class Empty()
Unit(单位值()更具体)绝对是空产品和元组.例如,它以无形的方式使用.