我正在学习scala并尝试了以下形式Scala Cookbook:
trait Animal
trait FurryAnimal extends Animal
case class Dog(name:String) extends Animal
case class Cat(name:String) extends Animal
Run Code Online (Sandbox Code Playgroud)
现在,当我做到以下时:
val x = Array(Dog("Fido"),Cat("Felix"))
Run Code Online (Sandbox Code Playgroud)
它显示结果为:
x:Array[Product with Serializable with Animal] = Array(Dog(Fido),Cat(Felix))
Run Code Online (Sandbox Code Playgroud)
虽然我知道案例类与Product trait混在一起
我没有得到的是: Product with Serializable with Animal
据我所知,产品与模式匹配有关
我确实谷歌它,但没有得到任何东西.请帮助我详细了解这个概念.
谢谢
我试图了解Scala对Case Classes的作用,使它们对类型擦除警告有所不同.
假设我们有以下简单的类结构.它基本上是Either
:
abstract class BlackOrWhite[A, B]
case class Black[A,B]( val left: A ) extends BlackOrWhite[A,B]
case class White[A,B]( val right: B ) extends BlackOrWhite[A,B]
Run Code Online (Sandbox Code Playgroud)
而你正试图像这样使用它:
object Main extends App {
def echo[A,B] ( input: BlackOrWhite[A,B] ) = input match {
case Black(left) => println( "Black: " + left )
case White(right) => println( "White: " + right )
}
echo( Black[String, Int]( "String!" ) )
echo( White[String, Int]( 1234 ) )
}
Run Code Online (Sandbox Code Playgroud)
一切都编译和运行没有任何问题.但是,当我unapply
自己尝试实现该方法时,编译器会发出警告.我使用了以下类结构与Main
上面相同的类: …
请考虑以下示例:
import shapeless._
case class Foo(bar: String, baz: Boolean)
val labl = LabelledGeneric[Foo]
Run Code Online (Sandbox Code Playgroud)
现在,类型labl
是(美化)
LabelledGeneric[Foo] {
type Repr =
FieldType[Symbol @@ String("bar"), String] ::
FieldType[Symbol @@ String("baz"), Boolean] ::
HNil
}
Run Code Online (Sandbox Code Playgroud)
它已经传达了我需要的信息,即案例类字段的名称.
我正在寻找的是一种从labl
某种方式走向某种方式的方式
"bar" :: "baz" :: HNil
Run Code Online (Sandbox Code Playgroud)
即将单例类型中包含的信息具体化为值.
这可能吗?我可以使用一个宏,但我觉得我最终会在无形状中重写与该GenericMacros
对象非常相似的东西,所以我想知道我是否可以直接利用它.
有没有办法依赖特征中case类中定义的方法?例如,复制:以下不起作用.不过,我不知道为什么.
trait K[T <: K[T]] {
val x: String
val y: String
def m: T = copy(x = "hello")
def copy(x: String = this.x, y: String = this.y): T
}
case class L(val x: String, val y: String) extends K[L]
Run Code Online (Sandbox Code Playgroud)
得到:
error: class L needs to be abstract, since method copy in trait K of type
(x: String,y: String)L is not defined
case class L(val x: String, val y: String) extends K[L]
^
Run Code Online (Sandbox Code Playgroud) 在Scala 2.9.1中,我得到以下行为:
class Foo {
case class X()
object X // this compiles
def bar() {
object Y // this compiles
case class Y()
case class Z()
object Z // won't compile (see below)
}
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨Object Z
:错误:Z已经被定义为(编译器生成的)案例类伴随对象Z.
在案例类定义之后,如果它们在函数定义中,则看起来不允许为案例类定义伴随对象.这是编译器错误还是故意的?如果是后者,为什么?
为了便于在Scala中使用Avro,我想基于存储在.avro文件中的模式来定义案例类.我可以尝试:
谢谢,任何建议表示赞赏.-Julian
我知道你不允许从案例类继承,但是你真的需要的时候会怎么做?我们在层次结构中有两个类,它们都包含许多字段,我们需要能够创建两个类的实例.这是我的选择:
我该怎么办?这不是一个常见的问题吗?
我想知道在Scala案例类中使用泛型是否可以节省一些样板代码.
让我们保存我有以下类hieararchy来模拟一个"变体"类型,它包含一组类型并允许使用模式匹配拆箱:
sealed abstract class Box;
case class DoubleBox(v: Double) extends Box;
case class StringBox(v: String) extends Box;
case class BooleanBox(v: Boolean) extends Box;
def typeName(b: Box) = b match {
case DoubleBox(v) => "Double"
case StringBox(v) => "String"
case BooleanBox(v) => "Boolean"
case _ => "Unknown"
}
Run Code Online (Sandbox Code Playgroud)
代码中可能存在一些地方,如果它们是泛型,那么处理叶子类更方便.就像是:
sealed abstract class Box;
case class TypedBox[T](v: T) extends Box;
def typeName2(b: Box) = b match {
case TypedBox[Double](v) => "Double"
case TypedBox[String](v) => "String"
case TypedBox[Boolean](v) => "Boolean"
case _ …
Run Code Online (Sandbox Code Playgroud) 为什么Spark中的模式匹配与Scala中的模式匹配不一样?请参阅下面的示例...函数f()
尝试在类上进行模式匹配,它在Scala REPL中工作但在Spark中失败并导致所有"???". f2()
是一种解决方法,可以在Spark中获得所需的结果.isInstanceOf()
,但我知道这是Scala中的错误形式.
任何帮助模式匹配Spark中这种情况下的正确方法将不胜感激.
abstract class a extends Serializable {val a: Int}
case class b(a: Int) extends a
case class bNull(a: Int=0) extends a
val x: List[a] = List(b(0), b(1), bNull())
val xRdd = sc.parallelize(x)
Run Code Online (Sandbox Code Playgroud)
尝试模式匹配在Scala REPL中工作但在Spark中失败
def f(x: a) = x match {
case b(n) => "b"
case bNull(n) => "bnull"
case _ => "???"
}
Run Code Online (Sandbox Code Playgroud)
在Spark中运行的解决方法,但是形式不好(我认为)
def f2(x: a) = {
if (x.isInstanceOf[b]) {
"b"
} else if (x.isInstanceOf[bNull]) {
"bnull"
} else …
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类型成员.
那么我的问题是,这可以在没有类型参数的情况下表达吗?
在更一般的上下文中,我正在探索类型成员可以用类型成员替换类型参数的程度,何时这样做是个好主意.
case-class ×10
scala ×10
apache-spark ×1
avro ×1
definition ×1
dotty ×1
generics ×1
rdd ×1
schema ×1
shapeless ×1
traits ×1
type-erasure ×1
types ×1
unapply ×1