他们似乎没有很好地混合:
abstract class A
case class B (var a: Int)(var b: String) extends A
case class C extends A
Run Code Online (Sandbox Code Playgroud)
以下内容不起作用:
B(1)("1") match {
case B(a)(b) => print("B")
case C() => print("C")
}
Run Code Online (Sandbox Code Playgroud)
问题是模式匹配和curried参数似乎不起作用.有解决办法吗?
我想匹配一些案例类.如果我不知道它们,我想匹配类必须扩展的指定特征.这看起来像
trait Event //root trait
trait Status extends Event //special trait
trait UIEvent extends Event //special trait
case class Results extends Event //concrete case class
case class Query extends Event //concrete case class
case class Running extends Status //concrete case class
case class Finished extends Status //concrete case class
case class Update extends UIEvent //concrete case class
Run Code Online (Sandbox Code Playgroud)
我运行以下测试
val events = List(Results, Query, Running, Finished, Update)
events foreach {
case Results => println("Got a Results")
case Running => println("Got a …Run Code Online (Sandbox Code Playgroud) 我认为Scala构造map(f).flatten相当于flatMap(f).但是通过这个例子,情况并非如此.我想知道案例类的作用是什么.如果我使用整数,两者都是等价的.但就我而言,我不能.
case class CTest(v: Int)
val s = Set(Map(CTest(0) -> List(0, 3), CTest(1) -> List(0, 2)))
val possibilities = s flatMap { m =>
val mapping = m flatMap {
case (label, destNodes) => destNodes map {
case nodes => (label, nodes) }
}
mapping
}
possibilities
Run Code Online (Sandbox Code Playgroud)
产量
Set((CTest(0),3), (CTest(1), 2))
Run Code Online (Sandbox Code Playgroud)
而
case class CTest(v: Int)
val s = Set(Map(CTest(0) -> List(0, 3), CTest(1) -> List(0, 2)))
val possibilities = s flatMap { m => …Run Code Online (Sandbox Code Playgroud) 我正在尝试执行以下操作
trait Stateful {
type State
}
case class SystemState(system: Stateful, state: system.State) // does not compile
Run Code Online (Sandbox Code Playgroud)
也就是说,类型state取决于(的值)system.但是,不支持:
非法依赖方法类型:参数出现在同一节中的另一个参数的类型或更早的参数中
使用函数参数,我可以将参数拆分为两个参数列表,这对于案例类构造函数是不可能的:
def f(system: Stateful)(state: system.State): Unit = {} // compiles
Run Code Online (Sandbox Code Playgroud)
我能做的最好的事情是:
case class SystemState[S](system: Stateful { type State = S }, state: S) // compiles
Run Code Online (Sandbox Code Playgroud)
但我认为没有类型参数应该是可能的,因为在dotty中,我认为类型参数是desugared类型成员.
那么我的问题是,这可以在没有类型参数的情况下表达吗?
在更一般的上下文中,我正在探索类型成员可以用类型成员替换类型参数的程度,何时这样做是个好主意.
我刚刚在Scala actors包中看到过这个case类:
case class ! [a](ch: Channel[a], msg: a)
Run Code Online (Sandbox Code Playgroud)
在JavaDoc中,它以下列形式描述了用法:
receive {
case Chan1 ! msg1 => ...
case Chan2 ! msg2 => ...
}
Run Code Online (Sandbox Code Playgroud)
为什么不是这样的:
receive {
case !(Chan1, msg1) => ...
case !(Chan2, msg2) => ...
}
Run Code Online (Sandbox Code Playgroud)
是砰的操作员!与以冒号结尾的方法类似的特殊情况:
我创建了一个名为LogActor的akka actor.LogActors的receive方法处理来自其他actor的消息并将它们记录到指定的日志级别.
我可以通过两种方式区分不同的关卡.第一个:
import LogLevel._
object LogLevel extends Enumeration {
type LogLevel = Value
val Error, Warning, Info, Debug = Value
}
case class LogMessage(level : LogLevel, msg : String)
Run Code Online (Sandbox Code Playgroud)
第二个:( 编辑)
abstract class LogMessage(msg : String)
case class LogMessageError(msg : String) extends LogMessage(msg)
case class LogMessageWarning(msg : String) extends LogMessage(msg)
case class LogMessageInfo(msg : String) extends LogMessage(msg)
case class LogMessageDebug(msg : String) extends LogMessage(msg)
Run Code Online (Sandbox Code Playgroud)
哪种方式更有效?是否需要更少的时间来匹配案例类或匹配枚举值?
(我读过这个问题,但没有任何答案提到运行时问题)
特别是关于模式匹配和案例类.考虑以下:
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) TL; DR:似乎类型别名的类型参数(例如type T[X<:Serializable])在作为变量,参数和其他情况引用时不强制执行它们的约束.但是,案例类会为其参数正确实施边界.
考虑设计用于表示泛型类型子集的类型别名.例如,让我们说我想要一个类型的Serializable事物列表:
scala> type SerializableList[T <: Serializable] = List[T]
defined type alias SerializableList
Run Code Online (Sandbox Code Playgroud)
现在说我想要一个带有这些参数的case类:
scala> case class NetworkDataCC(things: SerializableList[_])
<console>:9: error: type arguments [_$1] do not conform to type SerializableList's type parameter bounds [T <: Serializable]
case class NetworkDataCC(things: SerializableList[_])
Run Code Online (Sandbox Code Playgroud)
嗯,这不起作用.Scala(恼人地)不带有类型的参数边界,但它很容易修复:
scala> case class NetworkDataCC(things: SerializableList[_ <: Serializable])
defined class NetworkDataCC
Run Code Online (Sandbox Code Playgroud)
好的.看起来不错.现在,如果我只想要一个带有这些东西的常规类,但我再次忘记显式声明类型边界.我期待一个错误:
scala> class NetworkData(val things: SerializableList[_])
defined class NetworkData
Run Code Online (Sandbox Code Playgroud)
等一下.没有错误......呵呵.
那么,现在我能做到这一点?
scala> new NetworkData(List(1))
res3: NetworkData = NetworkData@e344ad3
Run Code Online (Sandbox Code Playgroud)
嗯,这似乎很破碎.案例类,当然可以正常工作(因为声明了限制):
scala> NetworkDataCC(List(1))
<console>:11: error: …Run Code Online (Sandbox Code Playgroud) Scala案例类具有默认的toString函数.但是当这个case类使用现有的toString()函数扩展一个特征时,它将变得无用.我该如何防止这种情况?