Young87

当前位置:首页 >个人收藏

scala中的一切皆对象

scala中的一切皆对象

单纯从面向对象的角度来看待scala,可以说scala就是一门纯面向对象的编程语言,因为在scala中,一切都可以看做是对象。

这点和java是不同的,java中区分基本数据类型和引用类型。可以说scala比Java的面向对象理念还彻底!

数字对象

scala> 5210000 + 1 *1024 / 1
res0: Int = 5211024

scala> (5210000).+(((1).*(1024))./(1))
res1: Int = 5211024

在java中第一行就是基本的运算,但是scala中认为一切皆是对象,所以每个数字都可以被当一个对象来处理,所以写成第二种写法的出来的结论是一样的。

注:如果写成1.+2会被scala编译器当做Double+Int处理。

类型对象

对于Boolean或者其他类型都可以被重写。

abstract class Boolean2 {

  //same as: if(cond) t else e
  def ifThenElse[T](t: => T, e: => T): T

  def && (x: => Boolean2): Boolean2 = ifThenElse(x, False) //If x is true, then return x. Else, return false
  def || (x: => Boolean2): Boolean2 = ifThenElse(True, x) //If x is true, return true. Else, return x
  def unary_! : Boolean2 = ifThenElse(False, True) //if x is true, return false. Else, return true

  def == (x: Boolean2): Boolean2 = ifThenElse(x, x.unary_!) //if x is true, return x. Else, return the negation of x
  def != (x: Boolean2): Boolean2 = ifThenElse(x.unary_!, x) //if x is true, return the negation of x. Else, return x

  def < (x: Boolean2): Boolean2 = ifThenElse(False, x)
}

object True extends Boolean2 {
  def ifThenElse[T](t: => T, e: => T) = t
}
object False extends Boolean2 {
  def ifThenElse[T](t: => T, e: => T) = e
}

函数对象

函数类型A => B只是类scala.Function1 [A,B]的缩写,定义如下:

package scala
trait Function1[A, B] {
  def apply(x: A): B
}

//---------引入协变、逆变

trait Function[-T, +U] {
  def apply(x: T): U
}

所以函数是apply方法的对象。我有在考虑是不是利用函数即对象这种实现(或者说特性)使得scala具有高等函数,因为将一个对象当做和数字变量等一样的一等公民是非常自然的一件事情。

object addOne extends Function1[Int, Int] {
    def apply(m: Int): Int = m + 1
}

println(addOne(1))

//2

对于需要更多参数(目前最多为22)的函数,还有其他的trait,如Function2, Function3, …, Function22。至于为啥是22,这就不太懂了。

函数值的扩展

对于一个如下的匿名函数将被扩展成:

(x: Int) => x * x

//---- expanded

{
  class AnonFun extends Function1[Int, Int] {
    def apply(x: Int) = x * x
  }
  new AnonFun
}

//----- shoter

new Function1[Int, Int] {
  def apply(x: Int) = x * x
}

函数调用的扩展

对于一个函数调用f(a, b)将被扩展成f.apply(a, b)

所以面向对象的转化将变成

val f = (x: Int) => x * x
f(7)

//-----

val f = new Function1[Int, Int] {
  def apply(x: Int) = x * x
}
f.apply(7)

方法与函数

那么其实你会发现,这样的话函数会继承函数,再继承函数,这样无限递归下去。

所以解决的方式是

对于如下的函数

def f(x: Int): Boolean = …

其实并不是Function类型的。只有当它被用于应该是Function类型的位置时,它才会自动转化为Function值,如下:

(x: Int) => f(x)

new Function1[int, Boolean] {
    def apply(x: Int) = f(x)
}

这种方式是eta-expansion。

参考资料

  1. 除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog

上一篇: 79页区块链报告:从理论到实践(附下载)

下一篇: scala中的泛型编程

精华推荐