2015-05-05 12 views
5

Próbuje grać z rozszerzeniami, ale mam problemy z uzyskaniem następujących pracy:Dlaczego to rozszerzenie typu podstawowego nie działa?

let value = -13 
abs(value) 

extension Int { 
    var abs:Int { 
     return abs(self) // -> Cannot invoke 'abs' with an argument list of type '(Int)' 
    } 
} 

value.abs 

Błąd kompilacji jest dziwne, ponieważ wyraźnie uruchamia funkcję abs() bezpośrednio powyżej z Int jako argument. Nadal mam kilka żarówek, które można wywołać dla generyków, jak sądzę. Oświeć mnie.

+0

Aha! Dziękuję obojgu. Teraz rozumiem. Pierwsza osoba, która edytuje swoją odpowiedź, pokazuje, że mogę skorygować wolną funkcję, ponieważ 'Swift.abs (self)' otrzymuje 'accept': D –

+0

Poza tym, dlatego nienawidzę ukrytego ja. –

Odpowiedz

4

Kompilator Swift jest zdezorientowany, ponieważ używa się zmiennej abs jako funkcji, której nie może wykonać. Teraz możesz spojrzeć na wszystkie odpowiedzi i zmienić nazwę zmiennej, ale nie dają one wglądu w to, jak działają funkcje Swift.

Swift automatycznie importuje strukturę Swift, w której definiuje swoje statyczne funkcje. Aby móc korzystać z tych funkcji, zwykle nie trzeba określać, że pochodzą one z architektury, ale w takich przypadkach należy określić, że chcesz użyć metody abs z frameworka Swift.

Więc po wszystkich wyjaśnień, oto kod, który będzie działać:

let value = -13 
abs(value) 

extension Int { 
    var abs: Int { 
     return Swift.abs(self) 
    } 
} 

value.abs 
2

Pojawia się tylko problem z rozwiązywaniem połączeń. To będzie działać:

let value = -13 
abs(value) 


extension Int { 
    var abs1:Int { 
     return abs(self) 
    } 
} 

value.abs1 

A to będzie działać zbyt:

extension Int { 
    var abs:Int { 
     return self < 0 ? -self : self 
    } 
} 

value.abs 
2

Problem polega na tym, że są przedłużające Int dodać zmienną o nazwie abs - który jest również nazwa funkcji, którą dzwonią.

Podczas próby wywołania funkcji abs() na Int, widzi zmienna abs który został utworzony i jest zdezorientowany, ponieważ myśli, że starają się wrócić tej zmiennej i nie rozumie dlaczego wysyłasz to parametr .

Jeśli zmienisz nazwę zmiennej na absoluteValue lub cokolwiek innego, to powinno działać.

let value = -13 
abs(value) 

extension Int { 
var absoluteValue:Int { 
     return abs(self) 
    } 
} 

value.abs 

Aktualizacja: Jak inni stwierdzili, można również rozwiązać ujednoznacznienie wykorzystania abs przez jawne wywołanie funkcji w ramach Swift. To powinno działać równie dobrze jak powyższe rozwiązanie.

let value = -13 
abs(value) 

extension Int { 
var abs:Int { 
     return Swift.abs(self) 
    } 
} 

value.abs 

Choć osobiście bym jeszcze przemianować moją nową funkcję do absoluteValue jak w pierwszym przykładzie, tak że jego jasne, że nie jest wywołanie Swift.abs() podczas korzystania zmienną abs.

0

Dzięki kierownictwu dwóch oryginalnych odpowiedzi (zderzenie między globalną funkcją bezpłatną a zmienną, którą definiowałem), należy je ujednoznacznić. Zamiast wykonywać własną implementację abs lub być zmuszonym do używania innej nazwy, mogę odpowiednio ustawić obszar wewnątrz abs() przy użyciu przestrzeni nazw .

extension Int { 
    var absoluteValue:Int { 
     return Swift.abs(self) 
    } 
} 

To daje mi to, co najlepsze z obu światów (IMO).

Powiązane problemy