zoukankan      html  css  js  c++  java
  • 【scala】占位符

    Scala语言为了让函数字面量更加精简,还可以使用下划线作为占位符,用来表示一个或多个参数

    我们用来表示的参数必须满足只在函数字面量中出现一次。

    我们用例子来看占位符的用法

    scala> val list = List(1,2,3,4,5)
    list: List[Int] = List(1, 2, 3, 4, 5)
    
    scala> list.filter( _ > 3 )//等同于 x => x > 3
    res0: List[Int] = List(4, 5)
    

    我们看到 _ 就好像是表达式中需要被填入的空,函数每次调用的时候这个空就被一个传入参数填上

    但是参数是依次填入的,不能重复。也就是说,像上例的 1,2,3,4,5.并不能从头再来依次。

    scala> val nums = List(1,2,3,4,5)
    nums: List[Int] = List(1, 2, 3, 4, 5)
    
    scala> nums.map((_,1)) //等同于 x => (x,1)
    res1: List[(Int, Int)] = List((1,1), (2,1), (3,1), (4,1), (5,1))
    

    当然,我们也可以使用多个占位符来表示多个参数。

    scala> val nums = List(1,2,3,4,5)
    nums: List[Int] = List(1, 2, 3, 4, 5)
    
    scala> nums.reduce( _+_ ) //相当于 a + b
    res2: Int = 15
    

    上例中,第一个占位符代表一个参数,第二个代表不同于第一个的参数。

    执行过程是这样的,先第一个参数 1 填上第一个占位符,第二个参数 2 填入第二个占位符,注意这里并不是参数列表从新填一次。

    执行1+2 = 3.因为reduce,3重新排入list中,list现在为3,3,4,5

    然后再次填入,3 + 3,list中变为 6,4,5

    依次类推。结果为 15.

    但是注意,我们在使用占位符的时候,编译器可能并没有足够的信息区推断你缺失的类型

    使用的时候不要盲目的省略,避免造成不必要的错误。

    scala> val f = _ + _
    <console>:11: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
           val f = _ + _
                   ^
    <console>:11: error: missing parameter type for expanded function ((x$1: <error>, x$2: <error>) => x$1.$plus(x$2))
           val f = _ + _
                       ^
    

    上面的例子就是,我们在定义 f 方法的时候只用了占位符来表示两个参数,但是编译器并不能推断出你的参数类型,报错。

    这个时候我们需要注明参数类型

    scala> val f = (_:Int) + (_:Int)
    f: (Int, Int) => Int = $$Lambda$1108/2058316797@4a8bf1dc
    
    scala> f(1,2)
    res5: Int = 3
    

    为什么我们开始的例子不用注明参数类型呢?因为我们在创建List的时候指明了类型为List[Int] 也就是编译器知道每个参数都为Int

    注意,当使用多个占位符的时候,代表的是不同的参数,不能是相同的参数。

    占位符也可以代替一个参数列表

    scala> def sum(a:Int,b:Int,c:Int) = a+b+c
    sum: (a: Int, b: Int, c: Int)Int
    
    scala> val a = sum _
    a: (Int, Int, Int) => Int = $$Lambda$1137/810864083@755a4ef5
    

    我们这里用了一个占位符代替了sum方法的参数列表,注意方法和占位符之间要有个空格,因为scala语言中方法名可以定义这样:sum_ 。

    我们在创建方法的时候并不能用占位符来代替参数列表,编译器并不能推断出占位符代表的东西。

    只能用占位符来代替已经明确的东西,也就是说来代替已经定义好的方法的参数列表。

    scala> val b = sum(1,_:Int,3)
    b: Int => Int = $$Lambda$1138/1122185195@3652dd19
    
    scala> b(2)
    res6: Int = 6
    

    我们还可以这么用,用占位符来代替其中的一个参数,然后调用的时候只需要传入一个参数即可。

    注意,这里代替的时候输出初始化一个参数,必须要表明参数类型。

    当然有的时候我们还可以更省略,不过只能用在明确需要函数的时候。

    scala> list.foreach(println _)
    1
    2
    3
    4
    5
    
    scala> list.foreach(println)
    1
    2
    3
    4
    5
    

      

  • 相关阅读:
    设计模式之实现状态模式
    一定要记住的OO设计原则:
    设计模式之实现命令模式
    设计模式之实现迭代器模式
    设计模式之实现观察者模式
    设计模式之实现策略模式
    设计模式之实现组合模式
    设计模式之实现几种工厂模式
    设计模式之实现装饰者模式
    pygame学习笔记(3)——时间、事件、文字
  • 原文地址:https://www.cnblogs.com/zzhangyuhang/p/9000088.html
Copyright © 2011-2022 走看看