这是我的基准代码:
def bm(duration: Long)(f: => Unit)={
val end = System.currentTimeMillis + duration
var count = 0
while(System.currentTimeMillis < end) { f; count += 1 }
count
}
val array = new scala.util.Random().alphanumeric.take(1000).toArray
(1 to 20).map { _ => bm(1000) { array.slice(100,200) } }.sum / 20
Run Code Online (Sandbox Code Playgroud)
运行这几次,我总是得到每秒大约150万片的数字.介于1.4和1.6之间.
现在,我这样做:
implicit class FastSlicing(val a: Array[Char]) extends AnyVal {
def fastSlice(from: Int, until: Int) = Arrays.copyOfRange(a, from, until)
}
(1 to 20).map { _ => bm(1000) { array.fastSlice(100,200) } }.sum / 20
Run Code Online (Sandbox Code Playgroud)
我得到的结果是每秒1600到1800万个切片.这速度提高了10倍以上 …
考虑一下:
class Foo { def foo = "foo" }
trait Bar { self: Foo =>
override def foo = "bar"
}
Run Code Online (Sandbox Code Playgroud)
我惊喜地发现这是可能的,并按预期工作:
new Foo with Bar foo
Run Code Online (Sandbox Code Playgroud)
返回"bar".问题是,是否可以Bar.foo调用Foo.foo,就像在"普通"继承案例中经常做的那样. override def foo = super.foo + "bar"不起作用(说"foo不是AnyRef的成员),也没有override def foo = self.foo + "bar"(它最终只是调用自身,并导致无限递归).我尝试了一些其他组合(如self.Foo.foo,Foo.this.foo等),但没有任何运气.
这不可能吗?
我试图理解为什么一个隐式转换在一个案例中起作用,而在另一个案例中却没有.这是一个例子:
case class Wrapper[T](wrapped: T)
trait Wrapping { implicit def wrapIt[T](x: Option[T]) = x.map(Wrapper(_))
class NotWorking extends Wrapping { def foo: Option[Wrapper[String]] = Some("foo") }
class Working extends Wrapping {
def foo: Option[Wrapper[String]] = {
val why = Some("foo")
why
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,我有从隐式转换Option[T]到Option[Wrapper[T]],并正在试图定义一个函数,该函数返回一个可选的字符串,是被隐式包装.
问题是,当我尝试Option[String]直接返回(NotWorking上面)时,我得到一个错误(found : String("foo") required: Wrapper[String]),如果我在返回之前将结果分配给val,那就会消失.
是什么赋予了?
我想知道为什么这不起作用(缺少参数类型)?
Seq(1,2,3).toSet.map(_ + 1)
Run Code Online (Sandbox Code Playgroud)
但是这样做:
val foo = Seq(1,2,3).toSet
foo.map(_ + 1)
Run Code Online (Sandbox Code Playgroud)
以及:(3)
Seq(1,2,3).toSet[Int].map(_ + 1)
Run Code Online (Sandbox Code Playgroud)
或这个:
Seq(1,2,3).toList.map(_ + 1)
Run Code Online (Sandbox Code Playgroud)
toSet在第一种情况下使它失去类型,在第二种情况下却没有使它松散的类型有什么特殊之处?
我对一个(内部)包有一个依赖项,其中包含一长串依赖项,其中大部分我不关心(我知道,它确实应该被清理并分成更小的包),其中一些已经固定得很旧了版本,与我的一些其他依赖项冲突。
它曾经对我来说使用旧版本的 pip (我认为是 18.0)工作得很好:我只是在 的末尾有这个包requirements.txt,它会安装我的新版本的冲突依赖项,然后警告我有关冲突的信息,我不关心。
但现在(使用21.1.2),我收到如下错误:
ERROR: Cannot install -r server/requirements.txt (line 41), my-package==2021.4.1.dev44+gd452819a91.d20210528 and pyyaml==5.4.1 because these package versions have conflicting dependencies.
The conflict is caused by:
The user requested pyyaml==5.4.1
openapi-spec-validator 0.2.8 depends on PyYAML>=5.1
dmy-package 2021.4.1.dev44+gd452819a91.d20210528 depends on pyyaml==3.12
To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict
ERROR: ResolutionImpossible: for help …Run Code Online (Sandbox Code Playgroud) 我试图回答这个问题,因为我认为我知道答案.事实证明,我不太了解:/
这是我做过的测试:
class Inst[T] {
def is(x: Any) = scala.util.Try { as(x) }.isSuccess
def as(x: Any): T = x.asInstanceOf[T]
}
scala> new Inst[String].is(3)
res17: Boolean = true
scala> new Inst[String].as(3)
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
... 33 elided
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?为什么只有第二次as投掷,而不是第一次?
假设我有一个生成器,它将一些分解成块的结果返回给我,我想把它放到一个平面列表中:
def pull(chunk: Chunk, result: Stream[Item] = Stream.empty): Stream[Item] = {
val soFar = chunk.items ++ result
if(chunk.hasNext) pull(generator.next(chunk), soFar) else soFar
}
Run Code Online (Sandbox Code Playgroud)
从概念上讲,这就是我想要的,除了它预先获取整个内容,我希望它是懒惰的.像这样的东西:
Stream.iterate(generator.first)(generator.next)
.takeWhile(_.hasNext)
.flatMap(_.items)
Run Code Online (Sandbox Code Playgroud)
几乎可以工作,但它丢弃了最后一块.
看起来我需要一个.takeUntil:喜欢takeWhile,但在终止之前通过整个链.我如何习惯性地这样做?
我正在从这样的java中读取文本BufferedReader:
Stream.continually(reader.readLine).takeWhile {
case null => reader.close; false
case _ => true
}
Run Code Online (Sandbox Code Playgroud)
这有效,但对我来说似乎有点笨拙.我希望能有像.whenDone上Stream,这样我就可以告诉它整个事情后关闭读者被消耗掉,然后就去做.takeWhile(_ != null).
有什么方法可以做到这一点我不知道吗?或者,也许,更好的方法来从Java得到线流Reader(如果它是一个InputStream,我只是做Source.fromInputStream了例子,但似乎并没有成为同等Reader......注意,这只能部分地解决但问题是,因为人们可能想与其他"可关闭的"对象做同样的事情 - ResultSet比如说一个例子)?
我的 build.gradle 中有这个:
test {
testLogging {
exceptionFormat 'full'
showExceptions true
showStackTraces true
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于 java(“普通”junit)测试,但是当我运行 scalatest 测试时,即使-i在命令行上,如果出现故障,我得到的只是这样的:
com.mypackage.mytests.ScalatestSpec > .apply should fail miserably FAILED
org.scalatest.exceptions.TestFailedException: 2 was not equal to 1
Run Code Online (Sandbox Code Playgroud)
没有回溯甚至行号被打印出来,我必须手动重新运行测试才能看到它实际失败的地方。我是否必须设置另一个特殊标志才能让它停止跟随我的输出?
所以,我试图制作一个 finagle 服务器,与哨兵交谈(不重要),并偶然发现了一个案例,我需要同时从两个类(不是特征)继承,让我们称它们为class SentryHandler extends Handlerand class TwitterHandler extends Handler,并假设,我需要创建MyHandler,从他们两个继承。
在愚蠢的片刻之后,当我认为不使用可怕的“委托模式”是不可能的时,我找到了一个解决方案:
trait SentryTrait extends SentryHandler
class MyHandler extends TwitterHandler with SentryTrait
Run Code Online (Sandbox Code Playgroud)
现在,这让我思考:拥有“特质”概念的目的是什么?如果这个想法是强制您可以从多个特征继承,但只能从一个类继承,那么绕过似乎非常容易。听起来class应该是继承的“主要”线(您“扩展具有特征的类”,但这也不是真的:您可以extend将特征带(或不带)一堆其他特征,并且根本没有课。
你不能实例化一个特征,但同样适用于抽象类......
我能想到的唯一真正的区别是特征不能有构造函数参数。但这有什么意义呢?我的意思是,为什么不呢?这样的事情会有什么问题?
class Foo(bar: String, baz: String) extends Bar(bar) with Baz(baz)
Run Code Online (Sandbox Code Playgroud)