scala> class A(implicit a: Int);
defined class A
scala> class B()(implicit a: Int);
defined class B
scala> new A()(1)
res1: A = A@159d450
scala> new B()(1)
res2: B = B@171f735
scala> new A(1)
<console>:7: error: too many arguments for constructor A: ()(implicit a: Int)A
new A(1)
Run Code Online (Sandbox Code Playgroud)
为什么Scalac在类声明中提供的隐式参数列表之前插入一个空参数列表?
从scalac来源的评论来看,这似乎是一个特征,而不是一个错误:
//如果它是唯一的参数部分,则将(隐式...)转换为()(隐式...)
我很想知道为什么这样做.我觉得这很令人惊讶.
UserGuide scalacheck项目的提到大小的发电机.解释代码
def matrix[T](g:Gen[T]):Gen[Seq[Seq[T]]] = Gen.sized {size =>
val side = scala.Math.sqrt(size).asInstanceOf[Int] //little change to prevent compile-time exception
Gen.vectorOf(side, Gen.vectorOf(side, g))
}
Run Code Online (Sandbox Code Playgroud)
没有为我解释.经过一番探索后,我了解到生成序列的长度并不依赖于生成器的实际大小(Gen对象中的resize方法根据javadoc"创建生成器的大小调整版本"(也许这意味着不同的东西?)).
val g = Gen.choose(1,5)
val g2 = Gen.resize(15, g)
println(matrix(g).sample) // (1)
println(matrix(g2).sample) // (2)
//1,2 produce Seq with same length
Run Code Online (Sandbox Code Playgroud)
你能解释一下我错过了什么,并举例说明你如何在测试代码时使用它们?
例如,List[T] forSome { type T }等同于List[_],但这是否适用于每种可能的用法,forSome或者是否存在forSome无法用等效的第二种语法替换的情况?
我在Scala中有这个类:
object Util {
class Tapper[A](tapMe: A) {
def tap(f: A => Unit): A = {
f(tapMe)
tapMe
}
def tap(fs: (A => Unit)*): A = {
fs.foreach(_(tapMe))
tapMe
}
}
implicit def tapper[A](toTap: A): Tapper[A] = new Tapper(toTap)
}
Run Code Online (Sandbox Code Playgroud)
现在,
"aaa".tap(_.trim)
Run Code Online (Sandbox Code Playgroud)
不编译,给出错误
错误:扩展函数缺少参数类型((x $ 1)=> x $ 1.trim)
为什么不推断类型String?从错误看来,隐式转换似乎触发了(否则错误将沿着" tap不是类的成员String"的行).似乎转换必须是Tapper[String],这意味着参数的类型是String => Unit(或(String => Unit)*).
有趣的是,如果我注释掉任何一个tap定义,那么它就会编译.
我很难解释主要隐式值或隐式转换所寻求的其他隐式值之间的行为差异.具体来说,这有效:
trait Foo[A]
implicit def fooString: Foo[String] = null
implicit def value[A](implicit foo: Foo[A]) = 5
> implicitly[Int]
5
Run Code Online (Sandbox Code Playgroud)
但这不是:
implicit def conversion[A](x: Int)(implicit foo: Foo[A]) = new {
def aMethod = 5
}
> 1.aMethod
could not find implicit value for parameter foo: test.Foo[A]
Run Code Online (Sandbox Code Playgroud)
变化:
implicitly还是隐式转换我得到以下结果:
Conversion/value Searching for Supplied | Works?
---------------- ------------- -------- | ------
conversion poly poly | yes
conversion poly mono | **no**
conversion mono poly | yes
conversion mono …Run Code Online (Sandbox Code Playgroud) 这是我项目中类型安全的麻烦违规,所以我正在寻找一种方法来禁用它.似乎如果函数采用AnyRef(或java.lang.Object),您可以使用任何参数组合调用该函数,Scala会将参数合并到Tuple对象中并调用该函数.
在我的情况下,该函数不期望一个元组,并在运行时失败.我希望在编译时捕获这种情况.
object WhyTuple {
def main(args: Array[String]): Unit = {
fooIt("foo", "bar")
}
def fooIt(o: AnyRef) {
println(o.toString)
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
(foo,bar)
Run Code Online (Sandbox Code Playgroud) 在scala中,"here docs"开始并以3结束 "
val str = """Hi,everyone"""
Run Code Online (Sandbox Code Playgroud)
但是如果字符串包含"""?如何输出Hi,"""everyone?
我想从Scala的不可变映射派生出来.它定义如下:
trait Map[A, +B]
Run Code Online (Sandbox Code Playgroud)
不幸的是,我的实现需要在B中保持不变.我尝试了以下内容,但没有成功:
def +(kv : (A, B)) : MyMap[A, B] = { ... }
override def +[B1 >: B](kv : (A, B1)) : MyMap[A, B1] =
throw new IllegalArgumentException()
Run Code Online (Sandbox Code Playgroud)
也许有一招@uncheckedVariance?
我需要用文本解析占位符abc $$FOO$$ cba.我和Scala的解析器组合器一起攻击了一些东西,但我对解决方案并不满意.
特别是,我在正则表达式中使用零宽度匹配器(?=(\$\$|\z))来停止解析文本并开始解析占位符.这听起来非常接近于scala邮件列表中讨论过的那些恶作剧,并且被多彩地解散了(这激发了这个问题的标题.)
所以,挑战:修复我的解析器没有这个黑客的工作.我希望看到从问题到解决方案的明确进展,因此我可以替换我的随机组装组合器的策略,直到测试通过.
import scala.util.parsing.combinator.RegexParsers
object PlaceholderParser extends RegexParsers {
sealed abstract class Element
case class Text(text: String) extends Element
case class Placeholder(key: String) extends Element
override def skipWhitespace = false
def parseElements(text: String): List[Element] = parseAll(elements, text) match {
case Success(es, _) => es
case NoSuccess(msg, _) => error("Could not parse: [%s]. Error: %s".format(text, msg))
}
def parseElementsOpt(text: String): ParseResult[List[Element]] = parseAll(elements, text)
lazy val elements: Parser[List[Element]] = rep(element)
lazy val …Run Code Online (Sandbox Code Playgroud) 我需要一组通用函数,但我不能按照我喜欢的方式完成它.我创造了一个
List[(Any)=>Unit]
Run Code Online (Sandbox Code Playgroud)
但是一旦我尝试插入一个函数,例如a
String=>Unit
Run Code Online (Sandbox Code Playgroud)
我收到一个错误.我怎么能声明一个不考虑参数和返回值类型的泛型函数集合?
scala ×10
implicit ×2
constructor ×1
function ×1
generics ×1
heredoc ×1
overloading ×1
parsing ×1
polymorphism ×1
rawstring ×1
scalacheck ×1
syntax ×1
tuples ×1
types ×1
variance ×1