Различия между использованием подчеркивания в этих методах Scala
В чем разница и название термина между этими подчеркиваниями из этих кодов: (см.handler(resource)
часть)
1.
def readFile[T](f: File)(handler: FileInputStream => Byte => T): T = {
val resource = new java.io.FileInputStream(f)
try {
val hh = handler(resource)_
hh(2)
} finally {
resource.close()
}
}
val bs = new Array[Byte](4)
readFile(new File("scala.txt")) {
input => b: Byte => println("Read: " + (input.read(bs) + b))
}
Я получил ошибку компиляции:
Error:(55, 29) _ must follow method; cannot follow Byte => T
val hh = handler(resource)_
^
Что это значит?
2.
def readFile[T](f: File)(handler: FileInputStream => Byte => T): T = {
val resource = new java.io.FileInputStream(f)
try {
val hh = handler(resource) _
hh(2)
} finally {
resource.close()
}
}
// Lower parts are same, so removed for brevity...
// ...
Результат такой же как нет. 1, я получил:_ must follow method
ошибка компиляции.
Я прочитал это потому, что подчеркивание используется для преобразования метода в функцию (ETA Расширение), но я также видел, что то же подчеркивание используется дляЧастичная прикладная функция без проблем, например:
val sum = (x: Int, y: Int) => x + y
val sum2 = sum _
Нет ошибки в этом случае.
3.
def readFile[T](f: File)(handler: FileInputStream => Byte => T): T = {
val resource = new java.io.FileInputStream(f)
try {
val hh = handler(resource)(_)
hh(2)
} finally {
resource.close()
}
}
//...
Этот работает отлично. Если я не ошибаюсь, подчеркивание в этом случае называетсяETA Расширение, это верно? Но я также читал отэто Q / Aэтот вид подчеркивания предназначен дляЧастичная прикладная функция, На той же странице кто-то также сказал, что этоСинтаксис заполнителя, Так какой из них правильный?
4.
def readFile[T](f: File)(handler: FileInputStream => Byte => T): T = {
val resource = new java.io.FileInputStream(f)
try {
val hh = handler(resource)
hh(2)
} finally {
resource.close()
}
}
//...
Этот не использует подчеркивание, но он работает отлично, как нет. 3. Мой вопрос по этому делу, в чем разница с нет. 3? Должен ли я использовать нет. 4 чем нет. 3? Это лишнее подчеркивание в нет. 3?
Извините за множество вопросов здесь, но это подчеркивание действительно сбивает с толку.
Почему-то я думал, что сложность подчеркивания в Scala совпадает со сложностью указателя и ссылки (* / & / &&) в C / C ++.
ОБНОВИТЬ:
5.
Я снова нашел кое-что интересное в подчеркивании:
scala> def sum(x: Int, y: Int) = x + y // sum is a method because of def
sum: (x: Int, y: Int)Int
scala> val sum2 = sum _ // sum2 is explicit ETA expanded function from sum
sum2: (Int, Int) => Int = <function2>
scala> sum2(2,3) // testing
res0: Int = 5
scala> val sum3 = (x: Int, y: Int) => x + y // sum3 is a function object
sum3: (Int, Int) => Int = <function2>
scala> val sum4 = sum3 _ // what happpened here?
sum4: () => (Int, Int) => Int = <function0>
scala> sum4()(2,3)
res2: Int = 5
Не могли бы вы рассказать мне, что случилось сsum4
? Почему результатsum3 _
имеет тип функции:() => (Int, Int) => Int
?
6.
List(1, 2, 3) foreach println _
В соответствии сэтот ответ, этоЧастично примененные функции, Хорошо, я вижу, что пробел перед подчеркиванием довольно сложный. Это на самом деле так же, как:
List(1, 2, 3).foreach(println(_))
Так что это действительно частично применяемая функция.
Но если бы я сделал это:
scala> List(1, 2, 3).foreach(println _+1) //#1
<console>:8: error: type mismatch;
found : Int(1)
required: String
List(1, 2, 3).foreach(println _+1)
^
scala> List(1, 2, 3).foreach(println _+"#") //#2 printed out nothing (why?)
scala> List(1, 2, 3).foreach(println 1+_) //#3
<console>:1: error: ')' expected but integer literal found.
List(1, 2, 3).foreach(println 1+_)
^
scala> List(1, 2, 3).foreach(println "#"+_) //#4
<console>:1: error: ')' expected but string literal found.
List(1, 2, 3).foreach(println "#"+_)
^
Новичок обычно считает подчеркивание в этом случае заполнителем, но я верю, что нет, не так ли?