Próbuję dowiedzieć się, jak zadeklarować zmienną statyczną w zakresie tylko lokalnie do funkcji w języku Swift.
W C może to wyglądać mniej więcej tak:
int foo() {
static int timesCalled = 0;
++timesCalled;
return timesCalled;
}
W Objective-C jest w zasadzie to samo:
- (NSInteger)foo {
static NSInteger timesCalled = 0;
++timesCalled;
return timesCalled;
}
Ale wydaje mi się, że nie mogę zrobić czegoś takiego w Swift. Próbowałem zadeklarować zmienną w następujący sposób:
static var timesCalledA = 0
var static timesCalledB = 0
var timesCalledC: static Int = 0
var timesCalledD: Int static = 0
Ale to wszystko prowadzi do błędów.
- Pierwsza narzeka: „Właściwości statyczne mogą być deklarowane tylko dla typu”.
- Drugi narzeka „Oczekiwana deklaracja” (gdzie
static
jest) i „Oczekiwany wzorzec” (gdzietimesCalledB
jest) - Trzeci narzeka „Kolejne instrukcje w wierszu muszą być oddzielone znakiem„; ”” (w odstępie między dwukropkiem a
static
) i „Oczekiwany typ” (gdziestatic
jest) - Czwarty dotyczy „Kolejne stwierdzenia w wierszu muszą być oddzielone znakiem„; ”” (w spacji między
Int
istatic
) oraz „Oczekiwana deklaracja” (pod znakiem równości)
struct Holder {…}
wewnątrz wielu funkcji i nie będą się one kolidować. Swift mógłby wytrzymaćstatic let
bez tegostruct
schematu.Inne rozwiązanie
func makeIncrementerClosure() -> () -> Int { var timesCalled = 0 func incrementer() -> Int { timesCalled += 1 return timesCalled } return incrementer } let foo = makeIncrementerClosure() foo() // returns 1 foo() // returns 2
źródło
Swift 1.2 z Xcode 6.3 obsługuje teraz statyczne zgodnie z oczekiwaniami. Z informacji o wersji beta Xcode 6.3:
Wygląda na to, że funkcje nie mogą zawierać deklaracji statycznych (jak zadano w pytaniu). Zamiast tego deklarację należy wykonać na poziomie klasy.
Prosty przykład pokazujący statyczną właściwość inkrementowaną wewnątrz funkcji klasowej (aka statycznej), chociaż funkcja klasy nie jest wymagana:
class StaticThing { static var timesCalled = 0 class func doSomething() { timesCalled++ println(timesCalled) } } StaticThing.doSomething() StaticThing.doSomething() StaticThing.doSomething()
Wynik:
1 2 3
źródło
static
może być celowa ze strony Apple, chociaż zawsze można zgłosić błąd, aby poprosić o zmianę. W Cstatic
ogranicza przechowywanie zmiennej do zakresu pliku źródłowego (który nie zawsze jest taki sam jak zakres klasy), podczas gdy umieszczenie deklaracji zmiennej określa zakres leksykalny (tj. Globalny vs wewnątrz funkcji vs wiele zagnieżdżonych{}
). W języku Swift zakres pamięci zawsze jest zgodny z zakresem leksykalnym, więc nie możesz mieć zmiennej, która jest leksykalna dla funkcji i ma pamięć globalną.Inne rozwiązanie
class Myclass { static var timesCalled = 0 func foo() -> Int { Myclass.timesCalled += 1 return Myclass.timesCalled } }
źródło