【Scala十五】Scala核心九:隐式转换之二

隐式转换存在的必要性,

 

在Java Swing中,按钮点击事件的处理,转换为Scala的的写法如下:

 

val button = new JButton
button.addActionListener(
    new ActionListener {
        def actionPerformed(event: ActionEvent) {
            println("pressed!")
        }
    }
)

 这是典型的Java-Style的代码,虽然使用Scala语法去写的,这个代码,真正有用的只有一句,println("pressed")

 

 

改写一下:

button.addActionListener((_: ActionEvent) => println("pressed!"))

 但是编译失败,原因是addActionListener方法只能接受ActionListener对象作为参数,而不能使用函数常量作为参数,为了消除这种gap,就得定义隐式转换,将函数(确切的说,是将带有ActionEvent类型的参数的函数)转换为ActionListener对象

 

implicit def function2ActionListener(f: ActionEvent => Unit) =
  new ActionListener {
       def actionPerformed(event: ActionEvent) = f(event) //直接赋值
  }
) 

 

隐式转换的工作流程:

The way this code works is that the compiler first tries to compile it as is, but it sees a type error. Before giving up, it looks for an implicit conversion that can repair the problem. In this case, it finds function2ActionListener. It tries that conversion method, sees that it works, and moves on.

 

implicit修饰符可以作用变量、function,class和object上

 

隐式转换的规则:

1. Marking Rule: Only definitions marked implicit are available

2. Scope Rule: An inserted implicit conversion must be in scope as a single identifier, or be associated with

the source or target type of the conversion.

3. One-at-a-time Rule: Only one implicit is tried

4. Explicits-First Rule: Whenever code type checks as it is written, no implicits are attempted.

如果编译时没有类型错误,Scala编译器就不会启动隐式转换功能,即使有满足条件的隐式转换存在

 

 

 

 

 

 

 

你可能感兴趣的:(scala)