Выполнить присваивание и операцию, используя троичный оператор + && в Objective-C? - PullRequest
2 голосов
/ 21 марта 2012

Во имя троичного блаженства (и за презрение к многословию) ... Я надеюсь и несколько удивлен, что ...

BOOL isItOpen = YES;
isItOpen = (isItOpen ? YES : NO); // yes, dumbie, it's open.

отлично работает ... но это ...

isItOpen = (isItOpen ? [it close] && NO : [it open] && YES);

Результаты в Invalid operands to binary expression ('void' and 'int')

Кажется, я не могу отследить простое да или нет относительно того, можно ли условно связывать операции с && (или ||), как это делают, скажем, BASH или PHP. Я пробовал различные комбинации & и &&, но безрезультатно ... так как я C идиот ... но если этот "способ сделать это" НЕ возможен, лингвистически ... есть ли другой - это как кратко? (т. е. не задействовано if)

Ответы [ 4 ]

3 голосов
/ 22 марта 2012

Различие, которое вы испытываете, связано с тем, что Objective-C имеет:

(a) истинные процедуры (пустые функции / методы), которые не возвращают значения;и (б) более сильная система типов, чем PHP

В вашем примере основная проблема (а) - вы вызываете методы, которые возвращают ничто , а ничто нене логическое значение.

В PHP-функциях всегда возвращается что-то , функция, определенная как возвращающая пустоту, фактически определяется как возвращающая «бесполезное» значение.Однако PHP преобразует практически все во что угодно (и делает это непоследовательно, для добавления «веселья»), поэтому «бесполезное» значение имеет логическое значение - хотя, вероятно, это зависит от фазы луны ;-) Эта функцияэто означает, что вы можете надежно связать «void» функцию после , которая возвращает значение - <expr convertible to boolean> && <"void" function> будет работать в PHP (но полученное логическое значение является произвольным).То же самое не будет работать в Objective-C ( не попытайтесь исправить это с помощью оператора запятой, у этого оператора есть скрытые ловушки).

Так что, если вы придерживаетесь функций /методы, которые возвращают либо логическое значение, либо тип, неявно или явно преобразуемый в логическое значение (например, для типов указателей nil - false, другие значения - true; для целочисленных типов 0 - false, все остальное - true), вы можете «условно связывать» операции.Если вы должны сделать это, это другой вопрос ...

PS Если вы хотите сбить с толку, это коротко:

(isItOpen = !isItOpen) ? [it open] : [it close];

, что сделает большинство людейсделать двойной дубль; -)

3 голосов
/ 21 марта 2012

Ваш код будет работать нормально, пока методы close и open, которые вы выполняете для it, возвращают логические значения.В противном случае, нет сигары.

3 голосов
/ 21 марта 2012

Если вы хотите использовать троичный оператор, вы можете сделать так:

isItOpen ? ([it close], isItOpen = NO) : ([it open], isItOpen = YES);

Или:

isItOpen ? [it close] : [it open];
isItOpen = !isItOpen;

Но это не хороший стиль программирования, и вам следует избегатьit.

Следующий код гораздо более читабелен (по крайней мере, программистом C / C ++ / Objective-C):

if (isItOpen)
    [it close];
else
    [it open];
isItOpen = !isItOpen;

В порядке предпочтения, я рекомендую использовать третийверсия кода, затем вторая, затем первая.

3 голосов
/ 21 марта 2012

Операторы C (и, соответственно, C ++ и Objective-C 1 ) образуют выражения ;они предназначены для оценки значения, а не для управления потоком программы.

Так что пока ?:, && и || все предлагают оценка короткого замыкания их аргументов, вы не можете использовать их для условного вызова произвольных функций; 2 для этого следует использовать традиционные конструкции потока управления (например, if).

You может использовать малоизвестный оператор запятой для достижения этой цели, но я настоятельно рекомендую вам не , потому что он очень однотипныйи трудно читать.Например:

isItOpen = condition ? (func1(), NO) : (func2(), YES);


На самом деле, я не знаю Objective-C.Всем известно, что это возможно! И под "произвольным" я подразумеваю функции, которые возвращают void, или тип, который неявно не преобразуется в bool в случае && и || или несовпадающий тип в случае ?:.
...