Троичный (условный) оператор в C

Я думаю, что идиоматический способ состоит в том, чтобы иметь класс case вместо того, чтобы идти против JSON AST вручную.

В вашем случае вы можете иметь поле Option[String].

case class MyModel( attributeName: Option[String] )
implicit val rw: ReadWriter[MyModel] = macroRW

read[MyModel](jsonString)

Но, судя по всему, вы можете сделать

json.obj.value.get("attributename").map(_.str)

, чтобы получить Option[String] обратно.

53
задан Jon Seigel 6 April 2010 в 15:18
поделиться

12 ответов

Тернарный оператор - это удобство синтаксиса и удобства чтения, а не сокращение производительности. Люди разделяются по существу для условных выражений различной сложности, но для кратких условий может быть полезно иметь однострочное выражение.

Более того, поскольку это выражение, как Чарли Мартин написал , это означает, что оно может появиться в правой части утверждения на C. Это ценно для краткости.

63
ответ дан 7 November 2019 в 08:12
поделиться

троичный = простая форма if-else. Он доступен в основном для удобства чтения.

0
ответ дан 7 November 2019 в 08:12
поделиться

Это синтетический сахар и удобное сокращение для кратких блоков if / else, которые содержат только один оператор. Функционально обе конструкции должны работать одинаково.

4
ответ дан 7 November 2019 в 08:12
поделиться

Есть много вещей в C, которые технически не нужны, потому что их можно более или менее легко реализовать в условия других вещей. Вот неполный список:

  1. , в то время как
  2. для
  3. функций
  4. структуры

Представьте, как бы выглядел ваш код без них, и вы можете найти свой ответ. Тернарный оператор - это форма «синтаксического сахара», которая, если ее использовать с осторожностью и умением, облегчает написание и понимание кода.

11
ответ дан 7 November 2019 в 08:12
поделиться

Иногда троичный оператор - лучший способ выполнить работу. В частности, когда вы хотите, чтобы результат троичного числа был l-значением.

Это не хороший пример, но я лучше рисую пробел в некотором значении. Одна вещь очевидна, это не часто, когда вам действительно нужно использовать троичную, хотя я все еще использую ее довольно часто.

const char* appTitle  = amDebugging ? "DEBUG App 1.0" : "App v 1.0";

Одна вещь, против которой я бы предостерегал, это связывание тройных вместе. Они становятся настоящими
проблема во время обслуживания:

int myVal = aIsTrue ? aVal : bIsTrue ? bVal : cIsTrue ? cVal : dVal;

РЕДАКТИРОВАТЬ : Вот потенциально лучший пример. Вы можете использовать троичный оператор для назначения ссылок и константных значений, где в противном случае вам нужно было бы написать функцию для обработки:

int getMyValue()
{
  if( myCondition )
    return 42;
  else
    return 314;
}

const int myValue = getMyValue();

... мог бы стать:

const int myValue = myCondition ? 42 : 314;

Что лучше, это спорный вопрос, который я выберу не делать дебатировать.

9
ответ дан 7 November 2019 в 08:12
поделиться

Компактность и возможность встроить конструкцию if-then-else в выражение.

11
ответ дан 7 November 2019 в 08:12
поделиться

Это важно для запутывания кода, например:

Look->       See?!

No
:(
Oh, well
);
38
ответ дан 7 November 2019 в 08:12
поделиться

В C реальная польза от него состоит в том, что это выражение вместо оператора; то есть вы можете иметь его в правой части (RHS) заявления. Таким образом, вы можете писать определенные вещи более кратко.

155
ответ дан 7 November 2019 в 08:12
поделиться

Некоторые из приведенных ответов великолепны. Но меня удивляет, что никто не упомянул, что его можно использовать для компактного применения корректности const .

Примерно так:

const int n = (x != 0) ? 10 : 20;

так в основном n - это const , начальное значение которого зависит от оператора условия. Самая простая альтернатива - сделать n не const , это позволит обычному , если его инициализировать. Но если вы хотите, чтобы он был const , это нельзя сделать обычным , если . Лучшая замена, которую вы могли бы сделать, это использовать вспомогательную функцию, подобную этой:

int f(int x) {
    if(x != 0) { return 10; } else { return 20; }
}

const int n = f(x);

, но троичная версия if гораздо более компактна и, возможно, более читабельна.

Но если вы хотите, чтобы он был const , это нельзя сделать обычным , если . Лучшая замена, которую вы могли бы сделать, это использовать вспомогательную функцию, подобную этой:

int f(int x) {
    if(x != 0) { return 10; } else { return 20; }
}

const int n = f(x);

, но троичная версия if гораздо более компактна и, возможно, более читабельна.

Но если вы хотите, чтобы он был const , это нельзя сделать обычным , если . Лучшая замена, которую вы могли бы сделать, это использовать вспомогательную функцию, подобную этой:

int f(int x) {
    if(x != 0) { return 10; } else { return 20; }
}

const int n = f(x);

, но троичная версия if гораздо более компактна и, возможно, более читабельна.

82
ответ дан 7 November 2019 в 08:12
поделиться

Поскольку никто еще не упомянул об этом, единственный способ получить умные операторы printf - использовать троичный оператор:

printf("%d item%s", count, count > 1 ? "s\n" : "\n");

Caveat : Существуют некоторые различия в приоритетах операторов при переходе с C на C ++, и они могут быть удивлены тонкой ошибкой (-ями), возникающей из них.

8
ответ дан 7 November 2019 в 08:12
поделиться

The fact that the ternary operator is an expression, not a statement, allows it to be used in macro expansions for function-like macros that are used as part of an expression. Const may not have been part of original C, but the macro pre-processor goes way back.

One place where I've seen it used is in an array package that used macros for bound-checked array accesses. The syntax for a checked reference was something like aref(arrayname, type, index), where arrayname was actually a pointer to a struct that included the array bounds and an unsigned char array for the data, type was the actual type of the data, and index was the index. The expansion of this was quite hairy (and I'm not going to do it from memory), but it used some ternary operators to do the bound checking.

You can't do this as a function call in C because of the need for polymorphism of the returned object. So a macro was needed to do the type casting in the expression. In C++ you could do this as a templated overloaded function call (probably for operator[]), but C doesn't have such features.

Edit: Here's the example I was talking about, from the Berkeley CAD array package (glu 1.4 edition). The documentation of the array_fetch usage is:

type
array_fetch(type, array, position)
typeof type;
array_t *array;
int position;

Fetch an element from an array. A runtime error occurs on an attempt to reference outside the bounds of the array. There is no type-checking that the value at the given position is actually of the type used when разыменование массива.

и вот определение макроса array_fetch (обратите внимание на использование тернарного оператора и оператора последовательности запятой для выполнения всех подвыражений с правильными значениями в правильном порядке как часть одного выражения):

#define array_fetch(type, a, i)         \
(array_global_index = (i),              \
  (array_global_index >= (a)->num) ? array_abort((a),1) : 0,\
  *((type *) ((a)->space + array_global_index * (a)->obj_size)))

Раскрытие для array_insert (который при необходимости увеличивает массив, как вектор C ++) даже более сложное, включая несколько вложенных тернарных операторов.

8
ответ дан 7 November 2019 в 08:12
поделиться

То же, что и

if(0)
do();


if(0)
{
do();
}
-3
ответ дан 7 November 2019 в 08:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: