2015-02-02 18 views
6

Otrzymuję błąd czasu kompilacji, którego odwołanie myFunc jest niejednoznaczne.Swift - Przypisywanie funkcji przeładowanej do zmiennej

func f (s: String) -> String { return "version 1: " + s } 
func f(sourceString s: String) -> String { return "version 2: " + s } 
var myFunc: (String)-> String = f as (sourceString : String)->String 

Jak mogę wyraźnie wskazać każdą wersję przeciążonej funkcji, f, w powyższym przykładzie? Jeśli skomentuję albo deklarację func f, to się skompiluje i będzie działać. Ale chciałbym wiedzieć, jak odwołać się do każdej z funkcji, jeśli obie są zadeklarowane. Dzięki.

+0

Daj mi znać, jeśli moja odpowiedź ci pomogła. Mogę spróbować pomóc więcej –

Odpowiedz

4

Ciekawe to. Nie sądzę, żeby było to możliwe bez robienia czegoś na wzór sugestii @ marcos. Problem ty to możesz „cast away” nazwiska w krotek:

let named_pair = (s: "hello", i: 1) 
named_pair.s // hello 

let anon_pair = named_pair as (String,Int) 
// or anon_pair: (String,Int) = named_pair, if you prefer 
anon_pair.s // no such member 's' 

Teraz załóżmy zdefiniować dwie funkcje identyczne z wyjątkiem jednego nazwał argumenty

func f(s: String, i: Int) { println("_: \(s)") } 
func f(#s: String, #i: Int) { println("s: \(s)") } 

Można połączyć go poprzez krotki z imieniem vs nienazwanych argumenty

f(named_pair) // prints s: hello 
f(anon_pair) // prints _: hello 

// but if you try to call a named argument function with unnamed tuples: 
func g(# s: String, # i: Int) { println("s: \(s)") } 
g(anon_pair) // compiler error 

let h = g 
h(anon_pair) // compiler error 
h(named_pair) // works 

Ale ponieważ można wyrzucać tych nazw można to zrobić:

// compiles and runs just fine... 
(g as (String,Int)->())(anon_pair) 
let k: (String,Int)->() = g 
// as does this 
k(anon_pair) 

I ta możliwość zrobienia tego oznacza, że ​​nie można użyć typu do rozróżnienia funkcji przeciążonej tylko nazwami argumentów, o ile mogę to stwierdzić.

+0

Dzięki za przemyślaną odpowiedź. Wielka dyskusja na ten temat przez wszystkich. Prędkość prędkości - bałem się tego. Nie tyle z praktycznego punktu widzenia (zawsze mogę zmienić nazwę funkcji, aby uniknąć przeciążenia), ale bardziej z perspektywy akademickiej.Wygląda na to, że biedni, że język obsługujący funkcjonuje jako pierwszorzędne typy danych, ma scenariusze, w których nie można jednoznacznie odwoływać się do przeciążonych funkcji. Ok - akademicki we mnie jest rozczarowany, ale pragmatyści przyznają to prawdopodobnie prawie nigdy nie pojawią się w "prawdziwym życiu" :-) –

+0

Innym podejściem, o którym myślałem, było zadeklarowanie drugiego jako zamknięcia przypisanego początkowo zmiennej. To też by zadziałało, ale znowu miałem nadzieję, że język ma sposób na odwołanie się do sygnatury funkcji, która zawierała ujednoznacznienie parametru nazwanego. –

1
  • Liczba argumentów powinna być różna.
  • Jeśli liczba argumentów jest taka sama, ich typy danych powinny różnić się od siebie o .

Przykład

 
func f(x : String) -> NSString { 
     return a 
    } 
func f(x : UInt) -> NSString { 
      return "{\(x)}" 
     } 
+3

Niekoniecznie. Funkcje w Swift mogą się różnić tylko zewnętrznymi nazwami parametrów. –

+0

Dzięki @IvicaM. Nie wiedziałem o tym. –

0

Nie sądzę, jest to możliwe. Można zadzwonić jeden lub drugi:

println(f("test")) // version 1: test 
println(f(sourceString: "test")) // version 2: test 
+0

Dzięki, Ivica. Nie mam problemu z wywoływaniem każdej funkcji. Chciałbym jednak, aby zamiast tego było zmienne odwołanie do każdego z nich (działając jako typy pierwszej klasy, powinny być w stanie jednoznacznie wskazać zmienną dla każdej funkcji). –

5

nie wiem jak to zrobić dokładnie to, co chcesz, ale może to pomoże:

var myFunc1: (String)-> String = { s in f(sourceString: s) } 
var myFunc2: (String)-> String = { s in f(s) } 

Teraz można nazwać:

let s1 = myFunc1("one") // returns "version 2: one" 
let s2 = myFunc2("two") // returns "version 1: two" 
+0

Dzięki za odpowiedź, Marcos. Zgadzam się, nie przeładowując, unikam problemu. Bardziej mnie interesuje, w jaki sposób mogę określić konkretny podpis funkcji, gdy jedyną różnicą jest w nazwanych parametrach. Moje zainteresowanie jest tak samo akademickie (ponieważ wspomniane prace będą działać). Czy jest jakiś sposób, aby ujednoznacznić odniesienie do funkcji inne niż oddzielne nazwy? –

Powiązane problemy