2016-11-03 5 views
0

Я относительно новичок в scala-функциях, и я запутался в том, как этот синтаксический сахар действительно работает и когда использовать определенный тип.Scala: функция без аргументов

Я написал 3 функции все, которые должны делать то же самое, но у меня возникают проблемы с пониманием того, почему Function0 по-разному ведут себя

версия 1

val fn1 : (String) => String = System.getProperty(_) 

println(fn1("os.name")); 

версии 2

val fn2 :() => String = System.getProperty("os.name") 

    println(fn2()); 

Версия 2 дает несоответствие типов; найдено: String требуется:() ⇒ снабжать струной, тетивой и т.п.

версия 3

val fn3 =() => System.getProperty("os.name") 

println(fn3()); 

Я понимаю, что для версии 2 уже знает Scala тип возвращаемого System.getProperty, но почему она производит эту конкретную ошибку, почему это делает не позволяйте мне явно указывать тип возврата. Я лично предпочитаю явные типы возвращаемых данных, поэтому мне не нужно погружаться в метод, чтобы увидеть, что он возвращает.

ответ

4

В val fn2 :() => String = System.getProperty("os.name") будет выполнен и возвращен значение строки System.getProperty("os.name"). Но вы говорите, что fn2 - это значение, которое является функцией, которая не принимает аргументов и возвращает строку.

Когда вы делаете System.getProperty(_), это похоже на выполнение x => System.getProperty(x), который является функцией, которая берет строку и возвращает строку. Вот почему работает первая версия.

+0

Извините за лат e ответ на это, если вторая функция интерпретируется как «значение, которое является функцией, которая не принимает аргумента и возвращает строку. Не будет ли первая функция считываться аналогичным образом, то есть возвращает функцию, которая берет строку и возвращает строку. Вместо этого компилятор выясняет, что вы муравьем, чтобы вернуть строку, а не функцию. – Asrar

1

Эта версия typecheck:

val fn2 :() => String =() => System.getProperty("os.name") 

Вызов fn2() здесь просто как вызов:

def fn2(): String = System.getProperty("os.name") 
fn2() 

В вашем fn1 например, подчеркивание предоставляет этот неявный синтаксис, который выглядит гораздо больше, как что вам нужно для случая с пустыми аргументами:

val fn1 : (String) => (String) = (s) => System.getProperty(s) 
+0

'def' - это методы, которые не являются объектами первого класса, в отличие от FunctionN. Поэтому 'val fn2:() => String' определенно не то же самое, что' def fn2(): String'. – pedrofurla

+0

Отредактировал свой ответ для ясности. В примере OP две модели, которые я написал, эквивалентны. 'def' нельзя передать как объекты, но я думаю, что это сравнение по-прежнему полезно. – Tim

Смежные вопросы