第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

Scala foreach奇怪的行為

Scala foreach奇怪的行為

我想在Scala中使用漂亮的單行代碼遍歷值列表。例如,這很好用:scala> val x = List(1,2,3,4)x: List[Int] = List(1, 2, 3, 4)scala> x foreach println1234但是,如果我使用占位符_,則會(huì)給我一個(gè)錯(cuò)誤:scala> x foreach println(_ + 1)<console>:6: error: missing parameter type for expanded function ((x$1) =>x$1.$plus(1))       x foreach println(_ + 1)                         ^
查看完整描述

3 回答

?
慕雪6442864

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊

這個(gè):


x foreach println(_ + 1)

等效于此:


x.foreach(println(x$1 => x$1 + 1))

沒有跡象表明的類型可能是什么x$1,并且說實(shí)話,打印函數(shù)沒有任何意義。


您(對(duì)我而言)顯然打算打印x$0 + 1,而x$0參數(shù)傳遞到的位置foreach。但是,讓我們考慮一下...... foreach以a作為參數(shù)Function1[T, Unit],其中T是列表的類型參數(shù)。foreach相反println(_ + 1),您傳遞給的是返回的表達(dá)式Unit。


如果您寫了,相反x foreach println,您將傳遞完全不同的東西。您將傳遞function(*)println,該函數(shù)接受Any并返回Unit,因此符合的要求foreach。


由于的擴(kuò)展規(guī)則,這有點(diǎn)令人困惑_。它擴(kuò)展到最里面的表達(dá)式定界符(括號(hào)或花括號(hào)),除非它們代替了參數(shù),在這種情況下,它意味著另一件事:部分函數(shù)應(yīng)用程序。


為了更好地解釋這一點(diǎn),請(qǐng)看以下示例:


def f(a: Int, b: Int, c: Int) = a + b + c

val g: Int => Int = f(_, 2, 3) // Partial function application

g(1)

在這里,我們將第二個(gè)和第三個(gè)參數(shù)應(yīng)用于f,并返回一個(gè)僅需要剩余參數(shù)的函數(shù)。請(qǐng)注意,它只能按原樣工作,因?yàn)槲抑赋隽说念愋蚲,否則我必須指出未應(yīng)用的參數(shù)的類型。讓我們繼續(xù):


val h: Int => Int = _ + 1 // Anonymous function, expands to (x$1: Int => x$1 + 1)

val i: Int => Int = (_ + 1) // Same thing, because the parenthesis are dropped here

val j: Int => Int = 1 + (_ + 1) // doesn't work, because it expands to 1 + (x$1 => x$1 + 1), so it misses the type of `x$1`

val k: Int => Int = 1 + ((_: Int) + 1) // doesn't work, because it expands to 1 + (x$1: Int => x$1 + 1), so you are adding a function to an `Int`, but this operation doesn't exist

讓我們k更詳細(xì)地討論,因?yàn)檫@是非常重要的一點(diǎn)?;叵胍幌逻@g是一個(gè)函數(shù)Int => Int,對(duì)嗎?所以,如果我要輸入1 + g,這有意義嗎?這就是在中所做的k。


使人們感到困惑的是他們真正想要的是:


val j: Int => Int = x$1 => 1 + (x$1 + 1)

換句話說,他們希望x$1替換對(duì)象_跳到括號(hào)之外,并跳到正確的位置。這里的問題是,盡管對(duì)他們來說合適的地方似乎很明顯,但對(duì)于編譯器來說卻并不明顯??紤]以下示例,例如:


def findKeywords(keywords: List[String], sentence: List[String]) = sentence.filter(keywords contains _.map(_.toLowerCase))

現(xiàn)在,如果將其擴(kuò)展到括號(hào)之外,我們將得到:


def findKeywords(keywords: List[String], sentence: List[String]) = (x$1, x$2) => sentence.filter(keywords contains x$1.map(x$2.toLowerCase))

這絕對(duì)不是我們想要的。事實(shí)上,如果_沒有得到由最里面的表達(dá)式分隔符為界,一個(gè)永遠(yuǎn)無法使用_嵌套map,flatMap,filter和foreach。


現(xiàn)在,回到匿名函數(shù)和部分應(yīng)用程序之間的混淆,請(qǐng)看這里:


List(1,2,3,4) foreach println(_) // doesn't work

List(1,2,3,4) foreach (println(_)) // works

List(1,2,3,4) foreach (println(_ + 1)) // doesn't work

由于操作符號(hào)的工作方式,第一行不起作用。Scala只是看到printlnreturn Unit,這不是foreach期望的。


第二行之所以起作用,是因?yàn)槔ㄌ?hào)使Scala println(_)可以整體評(píng)估。這是一個(gè)部分函數(shù)應(yīng)用程序,因此它返回Any => Unit,這是可以接受的。


第三行不起作用,因?yàn)樗黖 + 1是匿名函數(shù),您將其作為參數(shù)傳遞給println。您并沒有成為println匿名函數(shù)的一部分,而這正是您想要的。


最后,很少有人期望:


List(1,2,3,4) foreach (Console println _ + 1)

這可行。為什么這樣做留給讀者練習(xí)。:-)


(*)實(shí)際上println是一種方法。在編寫時(shí)x foreach println,您沒有在傳遞方法,因?yàn)闊o法傳遞方法。相反,Scala創(chuàng)建一個(gè)閉包并將其傳遞。它像這樣擴(kuò)展:


x.foreach(new Function1[Any,Unit] { def apply(x$1: Any): Unit = Console.println(x$1) })


查看完整回答
反對(duì) 回復(fù) 2019-11-30
?
拉風(fēng)的咖菲貓

TA貢獻(xiàn)1995條經(jīng)驗(yàn) 獲得超2個(gè)贊

下劃線有點(diǎn)棘手。根據(jù)規(guī)范,該短語:


_ + 1

相當(dāng)于


x => x + 1


x foreach println (y => y + 1)

產(chǎn)量:


<console>:6: error: missing parameter type

           x foreach println (y => y + 1)

如果您在其中添加一些類型:


x foreach( println((y:Int) => y + 1))

<console>:6: error: type mismatch;

 found   : Unit

 required: (Int) => Unit

           x foreach( println((y:Int) => y + 1))

問題是您要傳遞一個(gè)匿名函數(shù)給println它,而它不能處理它。您真正想要做的是(如果您嘗試將繼承者打印到列表中的每個(gè)項(xiàng)目上):


x map (_+1) foreach println


查看完整回答
反對(duì) 回復(fù) 2019-11-30
?
喵喵時(shí)光機(jī)

TA貢獻(xiàn)1846條經(jīng)驗(yàn) 獲得超7個(gè)贊

Welcome to Scala version 2.8.0.Beta1-prerelease (Java HotSpot(TM) Client VM, Java 1.6.0_17).

Type in expressions to have them evaluated.

Type :help for more information.


scala> val l1 = List(1, 2, 3)

l1: List[Int] = List(1, 2, 3)


scala>


scala> l1.foreach(println(_))

1

2

3


查看完整回答
反對(duì) 回復(fù) 2019-11-30
  • 3 回答
  • 0 關(guān)注
  • 1138 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)