2014-06-30 11 views
6

W celu C, jeśli miało następującą właściwość: metoda powrotu szereg obiektów myArraySwift count opcjonalnie Tablica

@property (strong, nonatomic) NSArray * myArray; 

wyglądałby następująco:

- (NSInteger) numberOfObjectsInMyArray 
{ 
    return [self.myArray count]; 
} 

to byłoby zwraca albo liczbę obiektów w tablicy, albo 0, jeśli myArray == nil;

Najlepszym odpowiednikiem mogę myśleć o zrobieniu tego w Swift jest:

var myArray: Array<String>? 

func numberOfObjectsInMyArray() -> Int 
{ 
    return myArray ? myArray!.count : 0 
} 

więc sprawdzanie opcjonalną macierz zawiera wartość, a jeśli tak rozpakować tablicę i zwrócić tę wartość, w przeciwnym wypadku zwraca 0.

Czy to jest właściwy sposób? A może jest coś prostszego?

+2

Być może zwrócić opcjonalne 'Int?'? –

+0

Opcjonalne 'Int' nie jest konieczne, ponieważ w każdym przypadku istnieje tutaj wartość zwracana przez wartość. – holex

+0

'return myArray? .count' ... tak, zdecydowanie krócej. Ale oczywiście polega to na wykorzystaniu wyniku w miejscu, w którym opcjonalne jest dozwolone. No good w 'func numberOfSectionsInTableView (tableView: UITableView!) -> Int' na przykład –

Odpowiedz

6

To wygląda na prostszy sposób.

Kod Objective-C jest krótszy tylko dlatego, że nil jest również formą 0, będącą językiem opartym na języku C.

Ponieważ szybka jest silnie typowana, nie ma takiego skrótu. W tym konkretnym przypadku wymaga trochę więcej wysiłku, ale generalnie pozwala zaoszczędzić większości bólów głowy spowodowanych przez luźne pisanie.


Czy w konkretnym przypadku istnieje powód, dla którego macierz jest opcjonalna? Możesz po prostu mieć pustą tablicę. Coś takiego może pracować dla Ciebie:

var myArray: Array<String> = [] 

func numberOfObjectsInMyArray() -> Int { 
    return myArray.count 
} 

(Source for this information)

+0

Podoba mi się! A Swift zapewniłby, że myArray zawsze ma wartość. Wielkie dzięki. –

+0

ponieważ wartość zerowa wskazuje na tablicę, która nie została ustawiona w stosunku do tablicy 0 zliczeń. – altagir

3

Jak na temat korzystania optional dla wartości zwracanej?

var myArray: Array<String>? 

func numberOfObjectsInMyArray() -> Int? { 
    return myArray?.count 
} 

Myślę, że ten sposób jest bezpieczniejszy.

(Source for this information)

+0

Dzięki @ King-Wizard. –

25

Spróbuj użyć nil coalescing operator.

według dokumentacji Apple:

NIL operator koalescencyjny (a ?? b) rozpakowuje opcjonalny A jeśli zawiera wartość, lub zwraca wartość domyślną b jeśli jest zerowa.

Więc funkcja mogłaby wyglądać następująco:

func numberOfObjectsInMyArray() -> Int { 
     return (myArray?.count ?? 0) 
    } 

zgadzam się z innymi, że może to być zły pomysł z wielu powodów (jak czyni to wygląda tam jest tablicą o liczbie "0", gdy w ogóle nie ma tablicy), ale hej, nawet złe pomysły wymagają implementacji.

EDIT:

Więc dodaję to, bo dwie minuty po tym, jak pisał tę odpowiedź, natknąłem powód robi dokładnie to, co autor chce zrobić.

Implementuję protokół NSOutlineViewDataSource w Swift. Jedną z funkcji wymaganych przez protokół jest:

optional func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int

Ta funkcja wymaga, aby powrócić liczby dzieci parametru item. W moim kodzie, jeśli element ma jakiekolwiek potomstwo, będą one przechowywane w tablicy, ja nie zainicjuję tej tablicy, dopóki faktycznie dodaję dziecko do tablicy.

Innymi słowy, w momencie dostarczania danych do NSOutlineView, children może być nil lub może być wypełnione, lub mogło zostać kiedyś wypełnione, ale później wszystkie obiekty zostały usunięte, w takim przypadku nie będzie nil, ale będzie to count będzie 0. NSOutlineView nie obchodzi, czy children jest nil - wszystko, co chce wiedzieć, to ile wierszy będzie potrzebować do wyświetlenia item 's children.

W tej sytuacji ma sens, aby zwrócić 0, jeśli children jest nil. Jedynym powodem wywołania funkcji jest ustalenie, ile rzędów będzie potrzebować NSOutlineView. Nie ma znaczenia, czy odpowiedź brzmi: 0, ponieważ children jest zerowa lub dlatego, że jest pusta.

return (children?.count ?? 0) zrobi to, czego potrzebuję. Jeśli children jest nil, zwróci 0. W przeciwnym razie zwróci count. Idealny!

+0

Użycie operatora koalesminacji zerowej zilustrowanego w tej odpowiedzi jest najczystszym rozwiązaniem problemu określonym w PO (najlepsza odpowiedź).Można kwestionować wybory interfejsu API, ale w przypadku starszego kodu jest to inne zwierzę. –

+0

Świetna odpowiedź, dziękuję! Gdybym tylko mógł wybrać 2 zwycięzców ... –