该Unit编译器生成的字节码的时候,因为它是类似于得到特殊的处理void在JVM上.但从概念上讲,作为scala类型系统中的一种类型,它似乎也在语言本身得到特殊处理(下面的例子).
所以我的问题是澄清这一点并理解使用的机制以及是否真的对该Unit类型进行了特殊处理.
例1:
对于"普通"scala类型Seq,如果方法返回Seq,则必须返回Seq(或更具体的类型Seq)
def foo1: Seq[Int] = List(1, 2, 3)
def foo2: Seq[Int] = Vector(1, 2, 3)
def foo3: Seq[Int] = "foo" // Fails
Run Code Online (Sandbox Code Playgroud)
前两个例子编译,因为List[Int]和Vector[Int]是的亚型Seq[Int].第三个失败,因为String不是.
但是,如果我改变了第三个例子返回Unit的是,它会编译并没有问题,运行,即便String 是没有的子类型Unit:
def foo3(): Unit = "foo" // Compiles (with a warning)
Run Code Online (Sandbox Code Playgroud)
我不知道在scala中允许此异常的任何其他类型.那么编译器Unit对类型系统级别的类型有特殊规则,或者是否存在某种更通用的机制,例如隐式转换.
例2:
我也不清楚单位如何在通常应用方差规则的情况下进行交互.
例如,我们有时会Future[Unit]在意外使用的地方遇到这个错误,map而不是flatMap创建一个 …
使用mongodb java驱动程序的第3版(特别是v3.0.1)来复制文档的惯用方法是什么?
我们有一个会话集合,当一个新会话被创建或修改时,我们想要在一个操作中插入它 - 而不是必须查询文档是否存在然后插入或替换.
我们的旧upsertion代码使用了scala驱动程序casbah 2.7.3.它看起来像:
import com.mongodb.casbah.MongoCollection
import com.mongdb.DBObject
val sessionCollection: MongoCollection = ...
val sessionKey: String = ...
val sessionDocument: DBObject = ... // Either create a new one, or find and modify an existing one
sessionCollection.update(
"_id" -> sessionKey,
sessionDocument
upsert = true
)
Run Code Online (Sandbox Code Playgroud)
在我们当前的项目中,我们只是使用普通的java 3.0.1驱动程序,我们正在使用BsonDocument而不是DBObject使它更具典型性.我尝试用以下内容替换上面的内容:
import com.mongodb.client.MongoCollection
val sessionCollection: MongoCollection = ...
val sessionKey: String = ...
val sessionDocument: BsonDocument = // Either create a new one, or find and modify …Run Code Online (Sandbox Code Playgroud) 我经常遇到这样的情况,即我有一些特征的工厂方法,并且参数的名称与特征的成员冲突导致它们被隐藏:
trait MyTrait {
val a: Int
val b: String
}
object MyTrait {
def apply(a: Int, b: String): MyTrait = new MyTrait {
val a = a // Recursive infinite loop.
val b = b
}
}
Run Code Online (Sandbox Code Playgroud)
所以通常我必须做一些丑陋的事情:
def apply(aA: Int, bB: String): MyTrait = new MyTrait {
val a = aA
val b = bB
}
Run Code Online (Sandbox Code Playgroud)
或制作参数的本地副本:
def apply(a: Int, b: String): MyTrait = {
val localA = a
val localB = b
new MyTrait {
val a …Run Code Online (Sandbox Code Playgroud) 我有一个方法,有4个参数,可以在块中使用.在每个块中,第一个参数始终相同:
// Block 1 - first parameter always "A"
foo(a="A", b="x", c="y", d="z")
foo(a="A", b=".", c=",", d="-")
foo(a="A", b="1", c="2", d="3")
// Block 2 - first parameter always "B"
foo(a="B", b="x", c="y", d="z")
foo(a="B", b=".", c=",", d="-")
foo(a="B", b="1", c="2", d="3")
Run Code Online (Sandbox Code Playgroud)
我想快速为每个块创建一个方法,这样我只需要指定其他3个参数.目前我可以这样做:
def fooCurried(a: String) = foo(a, _: String, _: String, _: String)
val fooA = fooCurreid("A")
fooA("x", "y", "z")
fooA(".", ",", "-")
fooA("1", "2", "3")
val fooB = fooCurried("B")
fooB("x", "y", "z")
fooB(".", ",", "-")
fooB("1", "2", "3")
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是我丢失了我的命名参数.他们变得 …
常规scala集合有一个漂亮的collect方法,它允许我filter-map使用部分函数在一个传递中执行操作.火花上有相同的操作Dataset吗?
我想它有两个原因:
filter-map样式操作减少到一次通过(尽管在火花中我猜测有优化可以为你发现这些东西)这是一个显示我的意思的例子.假设我有一系列选项,我想提取并加倍定义的整数(a中的那些Some):
val input = Seq(Some(3), None, Some(-1), None, Some(4), Some(5))
Run Code Online (Sandbox Code Playgroud)
方法1 - collect
input.collect {
case Some(value) => value * 2
}
// List(6, -2, 8, 10)
Run Code Online (Sandbox Code Playgroud)
这collect使得这个语法非常简洁,并且一次通过.
方法2 - filter-map
input.filter(_.isDefined).map(_.get * 2)
Run Code Online (Sandbox Code Playgroud)
我可以将这种模式带到火花上,因为数据集和数据框有类似的方法.
但是,我不喜欢这个这么多,因为isDefined和get看起来像代码异味给我.有一个隐含的假设,即地图只接收Somes.编译器无法验证这一点.在一个更大的例子中,开发人员更难发现这种假设,开发人员可能会交换过滤器并映射,例如,不会出现语法错误.
方法3 - fold*操作
input.foldRight[List[Int]](Nil) {
case (nextOpt, acc) => nextOpt match {
case Some(next) => next*2 :: acc
case None => …Run Code Online (Sandbox Code Playgroud)