2016-06-28 2 views
0

Я пытаюсь реализовать функцию, которая условно называется условным, если дополнительный объект, возвращаемый функцией, реализует конкретный протокол. Я изо всех сил с синтаксисом ... он говорит мне:Unwrap необязательно как условный объект, который реализует интерфейс

Braced block of statements is an unused closure 

и

Expected { after if condition 

Пример:

class SomeType { 
} 

class Something { 
    func doSomething() 
} 

protocol Foo { 
    func foo() -> SomeType 
} 

class Bar { 
    var whatever : SomeThing 
} 

extension Bar { 
    var handler : SomeThing? { 
     return whatever 
    } 
} 

class FooBar { 
    func doSomething(bar : Bar) { 
     // Assuming that bar's handler is set and implements Foo then use foo... 
     let foo = bar.handler as SomeThing : Foo { 
      ... 
      foo.doSomething() 
      ... 
      foo.foo() 
     } 
    } 
} 

Я мог бы сделать это:

if let foo = bar.handler! as? Something { 
    if (foo is Foo) { 
     foo.doSomething() 
     (foo as Foo).foo() 
    } 
} 

Или это:

if let fubar = bar.handler! as? Something, let foo = fubar as? Foo { 
    fubar.doSomething() 
    foo.foo() 
} 

Но я надеюсь, что есть более чистый способ

+0

'bar.handler as? Foo'? Это будет работать, только если 'Foo' не использует' Self' и не имеет связанных типов. – zneak

+0

@zneak Предположим, что это не так. – Tibrogargan

+0

Не так ли? Не имеет связанных типов и не использует Self? – zneak

ответ

0

Это, по-видимому, самый чистый способ сделать это.

if let foo:Something = bar.handler! where foo is Foo { 
    foo.doSomething() 
    (foo as Foo).foo() 
} 
0

Это очень неясное из этого кода именно то, что вы пытаетесь сделать, но если вы пытаетесь сделать это полностью динамически (решая все во время выполнения) вы, вероятно, сражаетесь с Свифт. Это часто возможно, но на каждом шагу вы собираетесь бороться с парадигмой языка. То, как вы обычно обрабатывать то, что вы описываете с перегрузками, так что это определяется во время компиляции, а не выполнения:

func doSomething<F: Foo>(handler : F) { ... things when F is Foo ... } 

Mixing много классов + дженерики + протоколы этот путь часто является источником сильной боли , поэтому вы должны тщательно спрашивать, почему Bar - это класс, а не структура (и, по крайней мере, почему это не final class). Трудно дать точный совет по очень высокому стилизованному вопросу, поэтому немного больше информации о проблеме, которую вы пытаетесь решить, может помочь.

Все, что сказано, вы можете вообще делать то, что вы описываете. Ваш синтаксис просто неверен. Что вы, возможно, имеете в виду:

if let foo = bar.handler as? Foo { 
+0

Роб, я отредактировал вопрос, чтобы показать два примера, которых я пытаюсь избежать. Я надеюсь, что есть способ, которым я могу получить один объект, который является созданием «Что-то», но только если он реализует протокол Foo – Tibrogargan

+0

. Это общий вопрос. Ответ - нет. Вам нужно поместить любые методы из Something и Foo в протокол, а затем потребовать этот протокол. –

+0

Ситуация у меня есть класс 'A', который имеет несколько подклассов, только некоторые из которых реализуют протокол. Класс контейнера имеет переменную-член типа 'A', которая на практике чаще всего является одним из подклассов. Ваше решение было бы непрактичным. – Tibrogargan

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