一个有趣的定义
shivawu
2010-03-27
今天想到这样一个类的定义方式
class A(f: A => Int) { val x = f(this) } 然后如果这样 new A(_.x + 10).x 会输出10 这只是一个简单的例子,不知道如果把x换成一种对象的类型会是什么结果,原理又是什么呢? |
|
night_stalker
2010-03-28
scala 是"伪脚本",类型是在编译期决定的。在运行构造器的时候,A 已经知道 x 是 Int 类型了,而 Int 的默认值是 0,故在调用 f(this) 的时候, this.x == 0。构造器再将 0 + 10 赋给 x,所以得到了以上结果。
Object 的默认值是 null,例子如下: class A(f: A => Object) { val x = f(this) } (new A(if(_.x == null) "null" else "not null")).x ps: 机器还没装 scala,尚未验证 …… 这个做法很糟糕,如果 x 是一个方法的话,就会无限循环或者爆栈了 …… |
|
cloverprince
2010-04-10
我理解:
类型在编译期推定: 由于f : A => Int,确定f的函数值是Int 由于val x = f(this),确定x的类型也是Int x是val,那么x的值在对象构造的时候确定: 对象构造的时候,x因为是Int型,所以x的初始值是0。 然后,根据val x = f(this),初始化这个x。得: x = f(this) = this.x + 10 = 0 + 10 = 10 println的时候,那个对象的x域的值就是10了。 实验证明,和ML,Haskell等函数式语言不同,Scala的各个val的初始化是从前到后一个一个地完成的,定义的顺序影响结果。如下程序: object HelloWorld { val a = b+1; val b = 5; def main(args : Array[String]) { println("a:["+a+"]"); println("b:["+b+"]"); } } /* 结果: a:[1] b:[5] */ 而这个程序: object HelloWorld2 { val b = 5; val a = b+1; def main(args : Array[String]) { println("a:["+a+"]"); println("b:["+b+"]"); } } /* 输出: a:[6] b:[5] */ |
|
fvzone
2010-04-13
新手来学习了!
|
|
Eastsun
2010-04-14
LZ如果把
class A(f: A => Int) { val x = f(this) } 改成 class A(f: A => Int) { lazy val x = f(this) } 你会发现更爽 |