3

Замечание. Можно лениво оценить простую инструкцию if. Ниже приведен пример, который будет печатать «это Foo» и «это бар», но я действительно хочу, чтобы распечатать только первую строку:Оценка ленивых функций в swift

func foo() { 
    println("this is foo") 
} 

func bar() { 
    println("this is bar") 
} 

func maybeFooOrBar(isFoo: Bool) { 
    let myFoo = foo() 
    let myBar = bar() 
    isFoo ? myFoo : myBar 
} 
+0

Я не понимаю ни слова. Это хорошо заданный вопрос. Я подозреваю, что это просто невозможно. (Я не знаю, что в некоторых случаях я бы опубликовал это как ответ). –

ответ

4

Не знаете, если это то, что вы хотите, вы можете использовать как тип

func foo() { 
    println("this is foo") 
} 

func bar() { 
    println("this is bar") 
} 

func maybeFooOrBar(isFoo: Bool) { 
    let myFoo = foo 
    let myBar = bar 
    let result = isFoo ? myFoo : myBar 
    result() 
} 

Затем, если вы callmaybeFooOrBar(true) напечатают первую функцию, callmaybeFooOrBar(false) Wii печати второй функцию

Кроме того, это может быть сделано в ясном пути

func maybeFooOrBar(isFoo: Bool) { 
    (isFoo ? foo : bar)() 
} 
+0

это работает как шарм –

1

Я не могу найти каноническое доказательство того, что Swift ISN 'л ленивый оценочный язык, но я уверен, что сообщество исправит меня, если я ошибаюсь!

Поскольку это не лень, вызовы метода просто исполняются в порядке, а не определяют, какие методы никогда не нужно будет вызывать.

Для достижения такого же эффекта вам необходимо реализовать «ленивое» поведение самостоятельно.

if isFoo 
{ 
    foo() 
} 
else 
{ 
    bar() 
} 

или более просто:

isFoo ? foo() : bar() 

Swift делает есть lazy instantiation. То есть вы можете сказать, что переменные не должны создаваться, пока они не будут использованы.

В Objective-C, это потребовало бы разработчику реализовать такое поведение вручную:

@property (nonatomic, strong) NSMutableArray *players; 
- (NSMutableArray *)players 
{ 
    if (!_players) 
    { 
     _players = [[NSMutableArray alloc] init]; 
    } 
    return _players; 
} 

В Swift, это намного проще и достигается с помощью lazy ключевого слова:

lazy var players = [String]() 
+0

Да, я знаю, что это прекрасно работает. Но действительно интересно сделать это, как в моем примере. –

+2

Проблема с примером в вашем вопросе заключается в том, что он игнорирует эффект вызова функции. Просто потому, что переменная result не используется, не означает, что вызов функции не сделал ничего другого - теоретически компилятор мог бы попытаться определить, можно ли оптимизировать вызов функции, но foo() или bar() могут приводят к многочисленным дополнительным вызовам функций, и это быстро становится очень сложным - гораздо проще для программиста не вызывать функцию, если она не нужна – Paulw11

+0

Джеймс, вы не можете передавать аргументы для ленивой инициализации var. Это не работает, если вы сделаете большую часть своих функций ссылочной прозрачной. –

0

я нашел очень простое решение следующего ответа Лео

func foo(a: Int)() { 
    println("this is foo") 
} 

func bar(b: Int)() { 
    println("this is bar") 
} 

func maybeFooOrBar(isFoo: Bool) { 
    let myFoo = foo(1) 
    let myBar = bar(2) 
    isFoo ? myFoo() : myBar() 
} 
Смежные вопросы