小编Col*_*lin的帖子

PartialFunction设计效率低下吗?

这是我一段时间都想知道的事情.我看到这种模式很多:

if (pf.isDefinedAt(in)) pf(in)
Run Code Online (Sandbox Code Playgroud)

通过将其分解为两个单独的调用,在#isDefinedAt中计算的所有模式也将在#apply中进行评估.例如:

object Ex1 {
  def unapply(in: Int) : Option[String] = {
    println("Ex1")
    if (in == 1) Some("1") else None
  }
}

object Ex2 {
  def unapply(in: Int) : Option[String] = {
    println("Ex2")
    if (in == 2) Some("2") else None
  }
}

val pf : PartialFunction[Int,String] = {
  case Ex1(result) => result
  case Ex2(result) => result
}

val in = 2

if (pf.isDefinedAt(in)) pf(in)
Run Code Online (Sandbox Code Playgroud)

哪个打印

Ex1
Ex2
Ex1
Ex2
res52: Any = 2
Run Code Online (Sandbox Code Playgroud)

在最坏的情况下,您的模式最后匹配,在调用PartialFunction时,您已经两次评估了模式/提取器.当匹配不仅仅是简单的类或列表模式匹配的自定义提取器时,这可能会变得低效(例如,如果您有一个解析XML文档并返回一些值对象的提取器)

PartialFunction#lift遭受同样的双重评估:

scala> pf.lift(2) …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala scala-2.8

13
推荐指数
1
解决办法
883
查看次数

为什么类型参数绑定T <:Comparable [T]为T = Int失败?

scala> class Foo[T <: Comparable[T]](val x : T)
defined class Foo

scala> (3: Int).asInstanceOf[Comparable[Int]]  
res60: java.lang.Comparable[Int] = 3

scala> new Foo(3)                              
<console>:13: error: inferred type arguments [Int] do not conform to class Foo's type parameter bounds [T <: java.lang.Comparable[T]]
       new Foo(3)
       ^
Run Code Online (Sandbox Code Playgroud)

第二个表达式是类型擦除的结果吗?

我将如何定义Foo以便我可以使用Int对其进行参数化,但仍然能够使用其实例变量执行某些排序行为?

java scala scala-2.8

13
推荐指数
3
解决办法
2391
查看次数

如何在Scala/Lift中以惯用方式处理空值检查?

即使Box和Option monad普遍存在,我们仍然需要在这里和那里检查空值.到目前为止,我提出的最好的方法是使用Box#!! 方法:

(Box !! possiblyNull).map(_.toString).openOr("")
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?我尝试使用Box的apply方法:

Box(possiblyNull).map(_.toString).openOr("")
Run Code Online (Sandbox Code Playgroud)

但编译器抱怨对重载定义的模糊引用,特别是:

[InType,OutType](value: InType)
(pf: PartialFunction[InType,OutType])net.liftweb.common.Box[OutType]
Run Code Online (Sandbox Code Playgroud)

我不确定为什么会发生这种情况,但我希望有一种更简洁,更简洁的方式来说"给我这个字符串的价值,或者只是".我正在考虑使用tryo,但认为这很浪费可以避免的例外情况.

scala lift scala-2.8

7
推荐指数
1
解决办法
3597
查看次数

在Scala中是否存在用于Rails"返回"方法的模拟?

在Rails中,可以使用:

returning Person.create do |p|
  p.first_name = "Collin"
  p.last_name = "VanDyck"
end
Run Code Online (Sandbox Code Playgroud)

避免必须这样做:

person = Person.create
person.first_name = "Collin"
person.last_name = "VanDyck"
person
Run Code Online (Sandbox Code Playgroud)

我认为前一种方式更清洁,重复性更低.我发现自己在Scala项目中创建了这个方法:

def returning[T](value: T)(fn: (T) => Unit) : T = {
  fn(value)
  value
}
Run Code Online (Sandbox Code Playgroud)

我知道由于对象倾向于不可变,它的实用性有限,但是例如使用Lift,在Mapper类上使用这种方法效果很好.

是否有Scala模拟用于"返回",我不知道?或者,在Scala中有类似的方法可以做到这一点吗?

scala ruby-on-rails scala-2.8

5
推荐指数
2
解决办法
312
查看次数

如何防止演员在其他长期演员面前挨饿?

这是使用Scala 2.8 Actors.我有一个可以并行化的长期工作.它包括大约65万单位的工作.我将它划分为2600个不同的单独子任务,并为每个子任务创建一个新的actor:

actor {
  val range = (0L to total by limit)
  val latch = new CountDownLatch(range.length)
  range.foreach { offset =>
    actor {
      doExpensiveStuff(offset,limit)
      latch.countDown
    }
  }
  latch.await
}
Run Code Online (Sandbox Code Playgroud)

这种方法效果很好,但总体上需要2 + h才能完成.问题在于,与此同时,我创建的任何其他演员都做正常的任务似乎被最初的2600名演员挨饿,这些演员也耐心地等待他们的时间在一个线程上运行但是等待的时间比任何新的演员要长.一起来.

我怎么能避免这种饥饿呢?

初步想法:

  • 而不是2600名演员,使用一个演员,顺序通过大量的工作.我不喜欢这个,因为我希望通过拆分它来尽快完成这项工作.
  • 而不是2600个演员,使用两个演员,每个演员处理整个工作集的不同一半.这可能会更好,但如果我的机器有8个核心怎么办?我可能想要利用更多.

UPDATE

有些人质疑Actors的使用,特别是因为消息传递能力没有在工作者中使用.我假设Actor是一个非常轻量级的抽象,围绕一个ThreadPool处于或接近相同的性能级别,只需手动编写基于ThreadPool的执行.所以我写了一个基准:

import testing._
import java.util.concurrent._
import actors.Futures._

val count = 100000
val poolSize = 4
val numRuns = 100

val ActorTest = new Benchmark {
  def run = {
    (1 to count).map(i => future {
      i * i
    }).foreach(_())
  }
}

val …
Run Code Online (Sandbox Code Playgroud)

concurrency scala scala-2.8 actor

5
推荐指数
1
解决办法
1622
查看次数

检查没有控制结构的值

我正在努力解决我在作业上遇到的问题.

如何在Java中检查值是否在一个范围内,例如1≤值≤31,而不使用if,switch或任何其他控制结构?

java math

4
推荐指数
2
解决办法
322
查看次数

使用具体类型扩展Scala Set

真的很难找出用一个代表一组具体类型的类扩展不可变集合.我这样做是为了尝试创建一个不错的DSL.

我想要一个类Thing,当你将'things'加在一起时,你得到一个ThingSet对象,它扩展了Set.

class Thing(val name:String){
  def +(other: Thing):ThingSet = new ThingSet() + other
}
Run Code Online (Sandbox Code Playgroud)

我只是无法弄清楚如何制作ThingSet对象.我知道我需要混合GenericSetTemplate,SetLike等特性.但我无法使它工作.

请问,任何人都可以给我一些指示,因为我找不到任何明确的东西可以借鉴.我试过看BitSet和HashSet实现,但迷路了.

scala scala-2.8

3
推荐指数
1
解决办法
2030
查看次数

如何在Actors中安全地使用ThreadLocal缓存?

我的应用程序最终通过Actors进行大量后台处理,特别是加载Mapper实例,然后对它们进行一些工作.这是非常重复的,我想在我的Actor代码中缓存一些这些查找.

我通常会使用ThreadLocal.但是,由于线程初始化是由Actor线程池处理的,所以它似乎是唯一一个初始化并随后清除ThreadLocal的地方是在actor的PartialFunction中接收传入的消息.

我现在正在做的是在我的Actor中创建另一个方法,如下所示:

override def aroundUpdates[T](fn: => T) : T = {
  clientCache.init {
    fn
  }
}
Run Code Online (Sandbox Code Playgroud)

init方法处理以清除ThreadLocal的finally块.我不喜欢这种方法,因为aroundUpdates只存在于设置缓存的目的,它闻起来像代码味道.

有一个更好的方法吗?

scala lift

1
推荐指数
1
解决办法
462
查看次数