代码之家  ›  专栏  ›  技术社区  ›  SwiftMango

如何在map中正确使用占位符语法?

  •  1
  • SwiftMango  · 技术社区  · 8 年前

    我正在尝试对简单映射使用占位符语法:

    Array(1,2,3).map(if(_ % 2 == 0) _ * 2)
    

    我原以为会有同样的效果:

    Array(1,2,3).map(i=>if (i%2==0) i * 2)
    

    它抱怨

    error: type mismatch;
     found   : Unit
     required: Int => ?
    

    我也试过:

    Array(1,2,3).map(if(_ % 2 == 0) _ * 2 else _)                    //with else
    Array(1,2,3).map(if((_:Int) % 2 == 0) (_:Int) * 2 else (_:Int))  //All typed
    Array(1,2,3).map(if((_:Int) % 2 == 0) 0 else 1)                  //Typed and specific return Int
    

    他们每个人都会犯错。在这种情况下如何正确使用这种语法?


    编辑

    链接指出 filter(_:Boolean) filter (_ == true) 应该可以,但我对特定类型的测试不起作用。这个 link 同时声明 if (_) x else y 应该有用,但对我来说不行。需要更多的解释。


    编辑2

    尝试:

    Array(true,false).map(if(_) 0 else 1)
    

    它起作用了。但我的情况是:

    Array(1,2,3).map(if((_) % 2 == 0) 0 else 1)
    

    不起作用。

    这种语法只支持这样简单的表达式吗?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Leo C    8 年前

    回复:你最初的问题是:

    Array(1, 2, 3).map(if (_ % 2 == 0) _ * 2)
    // error: missing parameter type for expanded function ...
    // error: type mismatch ...
    

    这个 _ 这种模式中使用的占位符表示匿名函数的位置参数,因此 if (_ % 2 == 0) _ * 2 相当于:

    if (x => x % 2 == 0) y => y * 2
    

    这就解释了 missing parameter 错误。这个 type mismatch 错误是由于缺少 else if 语句,强制编译器返回 Unit :

    Array(1, 2, 3).map(i => if (i % 2 == 0) i * 2 else i)
    // res1: Array[Int] = Array(1, 4, 3
    

    考虑到您需要多次指定单个输入,我不确定它是否适合您。

    正如您已经注意到的,这个占位符语法确实有其局限性,对于相对简单的情况,应该将其视为一个方便的缩写。像 if (_ % 2 == 0) 0 else 1) 外壳,嵌套 γ 在一个 map 一般情况下工作不好。例如:

    List("a", "b", "c").map(_ * 3)
    // res2: List[String] = List(aaa, bbb, ccc)
    
    List("a", "b", "c").map((_ + " ") * 3)
    // error: missing parameter type for expanded function ...
    

    有关更多用法,请参阅: γ 这里是一个 SO link 和A Scala doc 关于常用符号,包括 γ .

    推荐文章