2013-03-16 3 views
0

Я следующий код, который работает и печать «Еогеасп выполнена»: Дженерик с кодовым блоком возвращающихся блоком

val buf = ArrayBuffer[() => Unit]() 
def add(o:() => Unit) = buf += o 
add(() => print("executed ")) 
print("foreach ") 
buf foreach (_()) 

Я хотел бы упростить линию 3, но он ломает в первой строке:

val buf = ArrayBuffer[=> Unit]() 
def add(o: => Unit) = buf += o 
add { print("executed ") } 
print("foreach ") 
buf foreach (_) 

Есть ли способ сделать это?

ответ

1

Если вы правильно поняли, что хотите сохранить фрагменты кода и оценить их позже. Синтаксис : => Type используется для передачи аргумента по имени, что означает, что он будет оцениваться каждый раз, когда он ссылается (вместо того, чтобы передать его функции). Насколько мне известно, единственный способ отложить оценку - создать вокруг себя какую-то обертку и сделать оценку доступной по вызову метода. В вашем случае просто не аргумент функция будет тонкая оболочка:

val buf = ArrayBuffer[() => Unit]() 
def add(o: => Unit) = buf += {() => o } 
add(() => print("executed ")) 
print("foreach ") 
buf foreach (_()) 
+1

* Исправление: * По-имя параметры _not_ ленивым! Они не оцениваются «когда это необходимо», они оцениваются - каждый раз, когда они ссылаются (динамически, а не статически) в вызываемом методе! –

+0

Спасибо, я отредактировал мой ответ – EECOLOR

2

Вы не можете использовать значения имен (=>T) как назначаемые объекты, только в качестве аргументов методов. Это значит, что вы не можете параметризовать ваш ArrayBuffer с помощью =>Unit. Ваш ArrayBuffer должен быть параметрирован с () => Unit.

Чтобы «поднять» значения имен в значениях функций, вы должны использовать синтаксис () => .... Вы можете сделать следующее:

val buf = ArrayBuffer[() => Unit]() 
def add(o: => Unit) = buf +=() => o 
add { print("executed ") } 
print("foreach ") 
buf foreach (_()) 
Смежные вопросы