1124 Оказывается, есть плюсы и минусы. Полезным источником информации является основополагающая книга «Программирование на Expert C» ( Глава 3 ). Вкратце, в C у вас есть несколько пространств имен: теги, типы, имена членов и идентификаторы . typedef
вводит псевдоним для типа и находит его в пространстве имен тега. А именно,
typedef struct Tag{
...members...
}Type;
определяет две вещи. Один тег в пространстве имен тегов и один тип в пространстве имен типов. Таким образом, вы можете сделать как Type myType
, так и struct Tag myTagType
. Объявления типа struct Type myType
или Tag myTagType
являются незаконными. Кроме того, в таком объявлении:
typedef Type *Type_ptr;
мы определяем указатель на наш тип. Поэтому, если мы объявим:
Type_ptr var1, var2;
struct Tag *myTagType1, myTagType2;
, то var1
, var2
и myTagType1
являются указателями на Type, но myTagType2
нет.
В вышеупомянутой книге упоминается, что структуры определения типов не очень полезны, поскольку они только спасают программиста от написания слова struct. Однако у меня есть возражение, как и у многих других программистов на Си. Хотя иногда оказывается необходимым запутывать некоторые имена (именно поэтому это не рекомендуется в больших базах кода, таких как ядро), когда вы хотите реализовать полиморфизм в C, это очень помогает , здесь можно найти подробности . Пример:
typedef struct MyWriter_t{
MyPipe super;
MyQueue relative;
uint32_t flags;
...
}MyWriter;
вы можете сделать:
void my_writer_func(MyPipe *s)
{
MyWriter *self = (MyWriter *) s;
uint32_t myFlags = self->flags;
...
}
Таким образом, вы можете получить доступ к внешнему элементу (flags
) через внутреннюю структуру (MyPipe
) посредством приведения. Для меня это менее запутанно приводить весь тип, чем делать (struct MyWriter_ *) s;
каждый раз, когда вы хотите выполнить такую функциональность. В этих случаях краткие ссылки имеют большое значение, особенно если вы интенсивно используете технику в своем коде.
Наконец, последний аспект с typedef
типами ed - это невозможность расширить их, в отличие от макросов. Если, например, у вас есть:
#define X char[10] or
typedef char Y[10]
, то вы можете объявить
unsigned X x; but not
unsigned Y y;
Мы на самом деле не заботимся об этом для структур, потому что это не относится к спецификаторам хранения (volatile
и const
).
Я просто отмечу, что я всегда имел тенденцию использовать конкатенацию на месте, пока не перечитал часть Руководства по стилю PEP общего стиля PEP PEP-8 для кода Python .
- Код должен быть написан так, чтобы не мешать другим реализациям Python (PyPy, Jython, IronPython, Pyrex, Psyco и т. Д.). Например, не полагайтесь на эффективную реализацию CPython конкатенации строк на месте для операторов в форме a + = b или a = a + b. Эти утверждения работают медленнее в Jython. В чувствительных к производительности частях библиотеки следует использовать форму '' .join (). Это гарантирует, что конкатенация происходит в линейное время в различных реализациях.
Исходя из этого, я перешел к практике использования объединений, чтобы я мог сохранить привычку как более автоматическую практику, когда эффективность чрезвычайно важна.
Поэтому я поставлю свой голос за:
ret = '@'.join([user, host])
Я принимаю вопрос, чтобы означать: «Это нормально делать это»:
ret = user + '@' + host
.. и ответ - да. Это прекрасно.
Вы должны, конечно, знать о классных вещах форматирования, которые вы можете делать в Python, и вы должны знать, что для длинных списков «соединение» - это путь, но для такой простой ситуации, как эта, что у вас это точно верно. Это просто и понятно, и производительность не будет проблемой.