作为测试,我写了这段代码:
object Ambig extends App {
def f( x:Int ) { println("Int" ) }
def f( x:String ) { println("String") }
f( null.asInstanceOf[Int ] )
f( null.asInstanceOf[String] )
f(null)
}
Run Code Online (Sandbox Code Playgroud)
我期望在最后一次调用f()时遇到错误,说这是不明确的.编译器接受了它,并产生了这个输出:
Int
String
String
Run Code Online (Sandbox Code Playgroud)
现在我猜这与Int不是AnyRef这一事实有关,因此f(null)的唯一f版本是f(x:String).但是,如果Int不能为null,则null.asInstanceOf [Int]是什么意思?repl说它是Int类型:
scala> :type null.asInstanceOf[Int]
Int
Run Code Online (Sandbox Code Playgroud)
但我真的不明白它是如何运作的.毕竟,如果我尝试将一个String转换为一个Int,那么所有的地狱都会崩溃:
scala> "foo".asInstanceOf[Int]
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source)
...
Run Code Online (Sandbox Code Playgroud)
当然这是预期的 - "foo"不能成为Int.但是两者都不能为null,那么为什么将int转换为Int工作呢?想必拳击某种形式,但类型仍然是Int,不能为null ...
我错过了什么?
我问的是一个让我最近困惑的基本问题.我想编写一个Scala For表达式来执行以下操作:
for (i <- expr1) {
if (i.method) {
for (j <- i) {
if (j.method) {
doSomething()
} else {
doSomethingElseA()
}
}
} else {
doSomethingElseB()
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,在多个生成器For表达式中,我不知道我可以在哪里放置表达式主体.
for {i <- expr1
if(i.method) // where can I write the else logic ?
j <- i
if (j.method)
} doSomething()
Run Code Online (Sandbox Code Playgroud)
如何在Scala Style中重写代码?
在回答StackOverflow问题时,我创建了一个Stream作为val,如下所示:
val s:Stream[Int] = 1 #:: s.map(_*2)
Run Code Online (Sandbox Code Playgroud)
并且有人告诉我应该使用def而不是val,因为Scala Kata抱怨(正如Eclipse中的Scala工作表一样)"前向引用扩展了对值s的定义".
但Stream文档中的示例使用val.哪一个是对的?
在此之前的Scala序列类型的2.10版本有类似的方法toList和toArray用于从一种类型转换为另一种.从Scala 2.10开始,我们有to[_]例如to[List]包含toList和朋友的东西,并且还使我们能够转换为新类型Vector,甚至可能转换为我们自己的集合类型.当然,它使您能够转换为仅作为类型参数知道的类型,例如to[A]- 很好!
但为什么旧的方法不被弃用?它们更快吗?是否有toList工作但to[List]不是的情况?我们是否应该优先选择其中一个工作?
我知道Scala有路径依赖类型,所以例如如果我在内部类中有一个类,我可以将一个方法的一个参数约束为另一个参数的内部类的实例:
class Outer { class Inner( x:Int ) }
val o1 = new Outer
val o2 = new Outer
val i11 = new o1.Inner(11)
val i12 = new o1.Inner(12)
val i21 = new o2.Inner(21)
def f[ A <: Outer ]( a:A )( i:a.Inner ) = (a,i)
f(o1)(i11) // works
f(o1)(i21) // type mismatch; i21 is from o2, not o1
Run Code Online (Sandbox Code Playgroud)
我可以使用类型投影创建从外部到内部的地图:
var m = Map[Outer,Outer#Inner]()
Run Code Online (Sandbox Code Playgroud)
但这会允许条目o1 -> i21,我不希望这是允许的.是否有任何类型的魔法要求值是其键的内部类的实例?也就是说,我想说些什么
var m = Map[Outer,$1.Inner]() // this doesn't work, of course
Run Code Online (Sandbox Code Playgroud) Martin Odersky在Scala Days 2011上发表了主题演讲.在其中,他为Lutz Prechelt在IEEE计算机33中的"七种编程语言的经验比较"一文中使用的着名电话号码短语编码器问题提出了令人印象深刻的解决方案.我试图获取代码从PDF,但结果充满了不间断的空间,很难摆脱.
此外,在给出的解决方案中有一些奇怪的东西,比如可以推断它们时明确提到的类型,以及带有List [String]值的Map被赋予默认值0.它只是一个类; 它不可执行.
有没有人有该示例代码的现成清理版本?
主题演讲视频和幻灯片可在此处获得:
我对 Rust 还比较陌生。我想编写一个函数,该函数将根据给定的闭包从集合创建 HashMap,该闭包从值生成键,例如
[derive(Debug)]
struct Foo {
id: u32,
name: String,
}
let foos = vec![
Foo { id: 1, name: "Bill".to_string() },
Foo { id: 2, name: "Mary".to_string() },
];
println!("{:?}", foos);
println!("{:?}", map_by(foos.iter(), |f| f.id)); // borrow the Foos
println!("{:?}", map_by(foos.iter(), |f| &f.name)); // borrow
println!("{:?}", map_by(foos.iter(), |f| f.name.as_str())); // borrow
println!("{:?}", map_by(foos, |f| f.id)); // consume the Foos
Run Code Online (Sandbox Code Playgroud)
我写了这个,它适用于上述用途:
fn map_by<I,K,V>(iterable: I, f: impl Fn(&V) -> K) -> HashMap<K,V>
where I: IntoIterator<Item = V>,
K: Eq …Run Code Online (Sandbox Code Playgroud) 为什么我不能实例化特征?编译器抱怨特征是抽象的,但我没有特征中的任何抽象方法或字段.
scala> trait A
scala> new A
<console>:9: error: trait A is abstract; cannot be instantiated
new A
^
Run Code Online (Sandbox Code Playgroud)