LINUX.ORG.RU

В Go есть ООП, а в C нет?

 ,


0

3

Встречаю такое утверждение, что в Go есть ООП, просто через структуры. Но в C тоже есть структуры, но почему-то говорят что там нет ООП, почему? Или в Go поверх структур еще много чего, чем C не может похвастаться?

И еще вопрос: Почему не использовать для тех же задач C вместо Go? Go юзают из за низкого порога входа или чего?


А так ли нужен этот ООП, вообще? Да и если сидят чуваки, пишут на Go, зачем им ещё что-то на C писать, если могут на Go?

th3m3 ★★★★★
()

Можно писать объектно-ориентированно хоть на ассемблере. Это не особенность языка, а подход к программированию. Другое дело, что некоторые языки имеют специальный сахар для этого, или даже настойчиво навязывают объектно-ориентированность (как в определённой мере делают Java и C#). Ни C ни Go специальных средств для работы с объектами не имеют, так что утверждение «в Go есть ООП, а в C нет» — либо бессмысленно, либо просто неверно, в зависимости от того, что имеется в виду под «есть ООП».

CrX ★★★★★
()

можно и структуры, но тебе придётся вручную заполнять vtable. Автоматических механизмов в си для этого нет и реализация ООП вручную - простой способ где-нибудь ошибиться и наоставлять багов, так что в самом языке его нет.
А так с тем же успехом ООП можно и в ассемблере реализовать, vtable там тоже можно реализовать самому, как и решить, в каком регистре передавать this.

mittorn ★★★★★
()

А пишут на Go, потому что он позволять писать безопасный код (о чём так мечтает Rust) с удовольствием, со скоростью разработки как Python, и скоростью исполнения почти как нативный C.

beastie ★★★★★
()

Меня не слушай я не программист, но…

Организация кода может быть в виде встроенных в язык выражений или в виде выраженном на языке. Это как например циклы, они могут быть встроены в язык в виде явной конструкции for или while, а могут быть выражены на нём через goto.

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

Встречаю такое утверждение, что в Go есть ООП

Задай этим людям вопрос, что такое ООП, они сначала тебе ответят каждый по разному, а потом подерутся. А если говорить об этом в рамках языков, то всё ещё веселее, так как тут скорее подразумевается, есть ли в языке явные синтаксические конструкции и эвристики которые явно выражают одно из составных частей ООП. Часто ещё говорят «в языке X ООП не полное», ну типа есть явные механизмы, но не все или не такие.

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

Если тебе лично удобно можешь рассматривать структуры в Си как объекты, объекты данных, а файлы модулями называть и так далее. Правда при общении с другими ты будешь испытывать трудности, и придётся говорить «как все», так и тут все (многие) говорят что в Си нет ООП так как там это не заложено явно в сам язык, а другие говорят что там есть ООП, так как его можно реализовать средствами самого языка.

LINUX-ORG-RU ★★★★★
()

Там своеобразное «ООП»:

type Car struct {
  // ...
}

type Batmobil struct {
  Car // наследум свойства и методы
}

Абстракция (есть везде и тут в тч, поэтому не рассматривается), Наследование (простое встраивание), Инкапсуляция (нет ее, мы не можем взять какой-то компонент фреймворка и переопределить что-то неэкспортируемое), Полиморфизм (через интерфейсы, в данном случае черех жопу). Структуры - это не классы. У классов есть конструкторы/деструкторы, публичные, приватные и защищенные свойства/атрибуты/методы/поля… Разработчики Go стремились сделать язык в который можно вкатиться за пару вечеров. У них это вышло в тч благодаря отсутствию ООП.

В Go самое крутое - это каналы, сборщик мусора и то, что он сам создает треды, те тебе этим заниматься не надо. Для сишников, конечно, это все сомнительные вещи, они привыкли закатывать солнце вручную… Это язык для вебни. На нем можно какие-то консольные утилиты делать, но там все так или иначе сводится к сети, сокетам… Это замена тормозной Java (она уже в принципе только с мобилками ассоциируется и серверным легаси) для тех, кто не хочет связываться с M$ с его сисярпом.

rtxtxtrx ★★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 3)

Писать в ОО стиле можно на C, но неудобно. Основная суть ОО стиля в современном понимании — это возможность привязать к данным функции, чтобы выбор функции был произведён как можно раньше, при создании переменной, а не в момент первого использования. В C это довольно неприятно делать вручную.

На поверхности этот код эквивалентен:

typedef struct Object Object;
void swap(Object *o) {}

type Object struct {}
func (o *Object) Swap() {}

В Го структура — это такая же структура как в C. При объявлении переменной в неё не записывается информация о привязанных функциях. Поэтому, в частности, мы не можем «динамично» заменить функцию:

// won’t compile
var o Object
o.Swap = func(Object *o) {}

То есть мы всё ещё работаем в обычной процедурной парадигме, легко переносимой на C. Суть ОО стиля в том, что мы можем заменить привязанные функции на раннем этапе.

В Go набор функций привязан к типу. Соответственно, изменив тип, мы можем изменить набор функций:

type FooObject Object
func (fo *FooObject) Swap() {}

var o Object
fo := FooObject(o)

И это ОО стиль.

(Другой, более распространённый способ — интерфейсы, которые позволяют забыть конкретные данные и оперировать чисто набором функций.)

Система типов C не сможет повторить приведённый пример. Поэтому его повторяют с помощью ручной работы — буквальным встраиванием функций в структуру, когда в структуре хранятся указатели на функции.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от Kolins

он просто использовал художественное преувеличение. на go нет ооп и не будет. это паскальщина 21-го века. в нем все сделано по заветам николашки вирта и с оглядкой на его языки (паскаль, модула, оберон)

rtxtxtrx ★★★
()
Ответ на: комментарий от kaldeon

Основная суть ОО

  1. Everything is an object,
  2. Objects communicate by sending and receiving messages (in terms of objects),
  3. Objects have their own memory (in terms of objects),
  4. Every object is an instance of a class (which must be an object),
  5. The class holds the shared behavior for its instances (in the form of objects in a program list),
  6. To eval a program list, control is passed to the first object and the remainder is treated as its message

TL;DR: OOP means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.

beastie ★★★★★
()
Ответ на: комментарий от beastie

Всё это важные теоретические аспекты, я лишь раскрыл важный практический вопрос — почему при схожих механизмах в C нет ООП, а в Go есть.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 2)
Ответ на: комментарий от kaldeon

В С нет сахара для ООП, но все механизмы ООП реализуемы в нём без особых проблем.

Даже больше, X11, GTK … даже части ядра – это всё ООП … на С.

К примеру: https://oshub.org/projects/retros-32/posts/object-oriented-design-patterns-in-osdev

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 4)

Go есть ООП

Такое же как и в Си - ехала функция через структуру - реализация конструктора и методов объекта, ехала структура через указатель на структуру - наследование.

Почему не использовать для тех же задач C вместо Go?

А ты попробуй. Если получится поймёшь, если нет, то будешь, как царь, презрительно на всех фыркать.

Ygor ★★★★★
()
Последнее исправление: Ygor (всего исправлений: 1)
Ответ на: комментарий от beastie

Ну да, ручной vtable. Не единственный и далеко не самый приятный метод. И это не сахар. Сахар может быть только синтаксическим, эти слова буквально образуют устойчивое словосочетание «синтаксический сахар».

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)

Почему не использовать для тех же задач C вместо Go?

Навскидку: в C нет ООП, нет замыканий, перегруженный синтаксис массивов, нет проверки выхода за границы массива, изменяемые строки, ручное управление памятью, слишком слабая типизация, сложная кросс-компиляция, нет зависимостей на уровне языка, нет рефлексии, бедная стандартная библиотека, сложный стандарт, UB, множество других способов отстрелить себе ногу.

Go юзают из за низкого порога входа или чего?

Это верная, но не единственная и не основная причина. Go создавался для крупномасштабной разработки. Подробности читать здесь.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 4)
Ответ на: комментарий от kaldeon

Навскидку: в C нет ООП

В Golang тоже. Если открыть википедию, то там про классы, объекты, и прочее. Связать функцию с типом по единому интерфейсу можно и через _Generic, как пример cos который выбирает по типу что вызвать, cos/cosf/cosl.

нет замыканий

Они просто реализуются через дополнительный аргумент void *data, учитывая любовь Go-программистов к повторению if err, не думаю что добавление аргумента и передача состояния у них вызовет раздражение.

перегруженный синтаксис массивов

Не знаю что это, перегрузка оператора []?

нет проверки выхода за границы массива

В любом достойном компиляторе.

изменяемые строки

Странное утверждение.

сложная кросс-компиляция

Интересно, во сколько раз больше платформ для кросскомпиляции он поддерживает чем Golang? Ну а вообще:

zig cc -o hello.exe hello.c -target x86_64-windows-gnu

нет рефлексии

Но есть макросы, благодаря ним можно легко создать таблицы преобразований, и их легко контроллировать, например сделать несколько таблиц для разных вариантов преобразования в json, как в Golang такое решается?

бедная стандартная библиотека

Этот минус затмевает плюс того, что С имеет доступ ко всей системе, и под С большое количество библиотек.

MOPKOBKA ★★★★★
()

Или в Go поверх структур еще много чего, чем C не может похвастаться?

Там есть интерфейсы.

И еще вопрос: Почему не использовать для тех же задач C вместо Go? Go юзают из за низкого порога входа или чего?

Он ближе к managed языкам, рантайм, GC, много проверок и нету такого прямого доступа к памяти.

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 1)
Ответ на: комментарий от qulinxao3

ООП не такая уж и сложная идея для реализации, мой любимый пример на FASM:

https://board.flatassembler.net/topic.php?t=9896

...
class TIndex
 field Index  : DWORD = 0 
 ; suppose we have 2 functions to work with Index
 function Inc
 ; just for example - let it be virtual
 virtual_function Dec
endclass
...

А уж на С совсем просто, GObject как доказательство. Генераторы/корутины тоже просто делаются:

#define CO_BEGIN static int state=0; switch(state) { case 0:
#define CO_END }
#define CO_YIELD(x) do { state=__LINE__; return x; case __LINE__:; } while (0)

void parser(int c) {
  CO_BEGIN;
  for (;;) {
    if (c == EOF)
      break;
    
    if (isalpha(c)) {
      do {
        add_to_token(c);
        CO_YIELD();
      } while (isalpha(c));
      got_token(WORD);
    }
    
    add_to_token(c);
    got_token(PUNCT);
    CO_YIELD();
  }
  CO_END;
}
Даже GC легко встраивается, но только консервативный, а вот точный GC уже сложно.

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 1)
Ответ на: комментарий от MOPKOBKA

Связать функцию с типом по единому интерфейсу можно и через _Generic

Честно говоря, сложно сравнить, но ставит под сомнение мой пример. Я вёл к тому, что в Go не нужно вручную делать vtable. Но ведь замена типа возможна и в C без vtable, можно просто обернуть в другую структуру.

Ну тогда только интерфейсы. Я считаю, этого достаточно, чтобы язык считался ОО. На мой взгляд, самый важный принцип ООП — это энкапсуляция, связывание данных и функций. Класс — не единственный подход, объекты в Go есть, наследование вообще не особо-то нужно в ООП.

Они просто реализуются через дополнительный аргумент void *data, учитывая любовь Go-программистов к повторению if err

Ужасно замыкания реализуются, на уровне ручных vtable. В одном ряду с if err даже не стоит.

Не знаю что это, перегрузка оператора []?

Не, просто синтаксис массивов. Как, например, определить двойной массив? Можно int foo[][nconst], но тогда придётся в функции передавать VLA. Или можно передавать привычный int**, но тогда определение массива будет int *foo[] = (int*[]){(int[]){1, 2, 3}}.

В общем, кошмар. Спустя годы мучений становится понятно откуда у этого кошмара ноги растут, но легче от этого не становится.

изменяемые строки

Странное утверждение.

Что странного? Какие бы данные не были в переменной, если это string, их нельзя изменить (кроме хаков).

В Си char* ничего не гарантирует. const char* является константой, но не гарантирует неизменяемость.

таблицы преобразований

А что это?

Этот минус затмевает плюс того, что С имеет доступ ко всей системе

А к чему в Go нет доступа? Сисколлы есть, вызов C есть.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 2)
Ответ на: комментарий от kaldeon

Они просто реализуются через дополнительный аргумент void *data, учитывая любовь Go-программистов к повторению if err

Ужасно замыкания реализуются, на уровне ручных vtable. В одном ряду с if err даже не стоит.

Да вроде близко, хотя в C есть setjmp/longjmp который позволяет строить исключения, в Golang есть подобный механизм?

int writepng_encode_image(mainprog_info *mainprog_ptr)
{
    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
  
    if (setjmp(mainprog_ptr->jmpbuf)) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        mainprog_ptr->png_ptr = NULL;
        mainprog_ptr->info_ptr = NULL;
        return 2;
    }
  
    png_write_image(png_ptr, mainprog_ptr->row_pointers);
  
    png_write_end(png_ptr, NULL);
  
    return 0;
}

Не, просто синтаксис массивов. Как, например, определить двойной массив?

Двумерный массив определяется просто int massiv[10][20], но по моему ты смешиваешь массивы непрерывные, и массивы указателей, тебе какой нужен? Для чего VLA я не понял.

const char* является константой, но не гарантирует неизменяемость

Ну без хаков с преобразованием ты не напишешь s[0] = 0 тоже.

таблицы преобразований

А что это?

Прием с препроцессором. Как в MFC, или Quake.

BEGIN_MESSAGE_MAP(CMyWnd2, CWnd)
   ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)
   ON_MESSAGE(WM_MYMESSAGE2, OnMyMessage2)
END_MESSAGE_MAP()

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

А к чему в Go нет доступа? Сисколлы есть, вызов C есть.

Даже если интерфейс простой, то излишне многословно, а если много макросов то еще сложнее, а если setjmp как в libpng, то наверное только писать С-обертку.

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 2)
Ответ на: комментарий от MOPKOBKA

В целом, подобного рода дискуссии обычно скатываются в «ничего особенного нет в вашем Go, всё это можно повторить в других языках».

Вопрос был «почему Go вместо C» и ответ «потому что проще», а не вопрос «возможна ли двусторонняя трансляция между C и Go» и ответ «нет, потому что C не умеет ничего».

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от MOPKOBKA

C есть setjmp/longjmp который позволяет строить исключения, в Golang есть подобный механизм?

Чет я не понял как связаны между собой замыкания (мы же говорим о closures?) и обработка ошибок.

Исключения в Go есть, но только для исключительных ситуаций, а не как нормальный поток выполнения. panic, recover.

ты смешиваешь массивы непрерывные, и массивы указателей, тебе какой нужен?

Ну да, специально смешиваю. Цель была показать сложность в работе с C.

Для чего VLA я не понял.

Чтобы передать непрерывный массив, разве не так?

void arrprint(int narr, int nnarr, int arr[][nnarr]) {
}

Но я сто лет не писал такой код, так что могу запутаться.

Прием с препроцессором … как в Golang такое решается?

В общем, не слышал о таком, поэтому ответить не смогу. В свободное время как-нибудь нагуглю.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от MOPKOBKA

Да вроде близко

Ну например нужно вернуть функцию, в которой есть несколько переменных из окружающего скоупа. Как это сделать? Придётся возвращать не просто функцию, а структуру с данными и указателем на функцию.

Возможно, но неприятно.

А обработка ошибок в Go — это благодать. Многословность компенсируется необходимостью явно проверять ошибки и избавляет от усложнённого потока выполнения, когда при простом чтении не знаешь когда произойдёт обрыв.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от kaldeon

Ну да, специально смешиваю. Цель была показать сложность в работе с C.

У С просто возможностей большей. Если нужна скорость, то в Golang придется руками вычислять индексы. Ну можно понять почему ты называешь это сложностью.

Чтобы передать непрерывный массив, разве не так?

Ты наверное такой код хотел написать?

int print_array(int width, int height, int array[width][height])
Можешь передавать в array переменную которая объявлена как int new_array[10][20], не обязательно ее делать VLA. Но если размер new_array определяется переменными, то его объявление будет таким int new_array[size1][size2].

А обработка ошибок в Go — это благодать. Многословность компенсируется необходимостью явно проверять ошибки и избавляет от усложнённого потока выполнения, когда при простом чтении не знаешь когда произойдёт обрыв.

Если код ответственно все проверяет, то он будет разростаться в несколько раз, за этими проверками не видно самого кода.

Есть схожая проблема у ручного управления памятью, невозможно писать элегантные функции как в функциональном программировании, даже хвостовая рекурсия ограниченна из за стадии очистки (в Golang тоже из за defer?).

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

Вот был понятный код с исключениями, такой:

try {
  l = sqrt(pow2(x1 - x2) + pow2(y1 * y2))
} catch (BigNumberException e) {
  log write
  exit or return
}
Или такой:
try {
  a = pow2(sub(x1, x2))
  b = pow2(mul(y1, y2))
  c = sqrt(add(a, b))
} catch (BigNumberException e) {
  log write
  exit or return
}
Без исключений он превращается в:
r1 = x1 - x2
if r1 == error {
  log write
  exit or return
}

r2 = pow2(r1)
if r2 == error {
  log write
  exit or return
}

r3 = y1 * y2
if r3 == error {
  log write
  exit or return
}

r4 = pow2(r3)
if r4 == error {
  log write
  exit or return
}

r5 = r1 + r4
if r5 == error {
  log write
  exit or return
}

r6 = sqrt(r5)
if r6 == error {
  log write
  exit or return
}

А это еще простой пример.

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 3)

Или в Go поверх структур еще много чего, чем C не может похвастаться?

в целом да. (нагуглил пример из интернета) Во-первых в golang у структур есть не только поля, но и методы

type Address struct {
	Street  string
	City    string
	Country string
}

func (a Address) GetAddress() string {
	return a.Street + ", " + a.City
}

во-вторых там есть наследование через композицию

type Restaurant struct {
	Name   string
	Rating int
	Address
}

func restaurantAddress(r Restaurant) string {
	return r.GetAddress()
}

в-третьих там есть интерфейсы с утиной типизацией

type WithAddress interface {
	GetAddress() string
}

func printAddress(a WithAddress) {
	fmt.Println(a.GetAddress())
}

func main() {
	r := Restaurant{
		Name:   "my",
		Rating: 5,
		Address: Address{
			Street:  "Lenina",
			City:    "Moscow",
			Country: "Russia",
		},
	}

	printAddress(r)
}

В Си это все естественно тоже можно сделать (как и все остальное) - засовывая указатели на функции в поля структур, кастуя структуры друг в друга, используя _Generic и т.п. Но - грустно.

Golang - это язык для случаев, когда тебе важнее быстро написать хороший поддерживаемый код, и наплевать что он будет работать например на 10% медленнее сишного и периодически отвлекаться на сборку мусора.

Особенно если речь идет о всякой асинхронщине с эвент лупами. Горутины, каналы и select в Го - это вообще не шутка, а серьезная технология, очень хорошо продуманная очень умными людьми для решения сложных задач. Если изучаешь Го, то изучай это в первом приоритете. Потому что основная ценность языка по сравнению с другими лежит именно там, а не в ООП или где-то еще.

Lrrr ★★★★★
()
Последнее исправление: Lrrr (всего исправлений: 1)

Почему не использовать для тех же задач C вместо Go?

Потому что в C:

  1. гораздо проще выстрелить себе в ногу
  2. нет GC из коробки
  3. нет автоматического управления ресурсами вообще (аналога defer)
  4. нет управления зависимостями из коробки (и не из коробки тоже)
  5. масса нюансов, которые требуют для разработки более подготовленных и умных людей, которых и так негде взять
Chiffchaff
()

В С изначально нет ООП, если нужно ООП, то С++

В C структура (struct) — это пользовательский тип данных, который позволяет объединять несколько переменных (поля) разных типов под одним именем. Это удобно, когда нужно хранить связанные данные вместе.

Как работает «под капотом»

  1. Компилятор выделяет память под все поля структуры подряд (с учетом выравнивания)
  2. Доступ к полям идёт по смещению (offset) от начала структуры.
  3. При передаче структуры в функцию по значению копируются все её поля. Поэтому часто используют указатели (struct *) для экономии памяти.

Что по поводу GObject.

GObject — это объектная система для языка C, являющаяся частью GLib , используемая в проектах вроде GTK

На мой взгляд GObect это имитация OOП

enep ★★★★★
()

Наоборот, для C есть первоклассная объектная система, на которой построен самый популярный свободный гуи-тулкит. Для го ничего подобного нет и не будет, и кодерам приходится подбирать крошки с сишного стола.

bread
()
Ответ на: комментарий от bread

Просто GUI перестал быть в приоритете. Можно заметить, что большинство новых проектов сейчас выпускается либо в виде веб-версии, либо в виде вебни, упакованной в Electron.

Был бы GUI сейчас приоритетным направлением, как 20-30 лет назад, добавили бы его и в Go из коробки. Но приоритеты у индустрии поменялись. Скоро всё будет в браузере и только в браузере, увы.

Chiffchaff
()
Ответ на: комментарий от mittorn

Но ты можешь сделать макросы, которые будут это делать автоматически. И соответственно, создавать объект не «руками» через struct struct_name object; а через макрос MAKE_OBJECT(struct struct_name, object) который все раскроет и инициализирует

zx_gamer ★★★
()
Ответ на: комментарий от Chiffchaff

Потому что в C:

Кто не ленится у того всё что нужно есть.

Например: динамическое управления объектами и переменных.

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

anonymous
()
Ответ на: комментарий от anonymous

Да, давайте все закатывать каждый раз солнце вручную.

Особенно это нужно бизнесу, вместо того, чтобы быстрее реализовывать новые фичи и исправлять ошибки.

Например, изменилось законодательство, и за неделю или месяц надо реализовать какую-нибудь новую отчётность. И разработчик такой приходит и говорит: «Я не ленивый, поэтому сейчас я с нуля напишу сборщик мусора, парсер XML, парсер JSON, и т.д. и т.п., ждите, через полгода может будет proof of concept для тестирования».

Вы где настолько оторвано от жизни живёте и работаете?

Chiffchaff
()
Ответ на: комментарий от Chiffchaff

Я не ленивый, поэтому сейчас я с нуля напишу сборщик мусора, парсер XML, парсер JSON, и т.д. и т.п., ждите, через полгода может будет proof of concept для тестирования

Готов ли ты взять на себя ответственность за написанный лично тобой парсер?
Готов ли ты взять на себя ответственность за парсер, написанный какими-то левыми чуваками, в который то политические лозунги, то быкдор впихнут?
Конечно писать каждый раз всё с нуля это тоже дикость, но не везде применимы библиотеки, особенно крупные

mittorn ★★★★★
()
Последнее исправление: mittorn (всего исправлений: 1)
Ответ на: комментарий от Chiffchaff

Вы где настолько оторвано от жизни живёте и работаете?

Млое из перечисленного для разработки прикладных проектов и используется.

anonymous
()
Ответ на: комментарий от mittorn

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

Chiffchaff
()
Ответ на: комментарий от anonymous

Ага. Надо мне было распарсить JSON, я поглядел, что есть: simplejson, json-p, jsoncpp. Взял jsoncpp как удобный, пишу. Написал, а мне говорят: «Зачем тут jsoncpp, мы другой библиотекой пользуемся» - ну и привет, пришлось переделывать. А писал бы я на Go, надо было бы всего лишь написать

import "encoding/json"
и дело в шляпе.

LongLiveUbuntu ★★★★★
()
Последнее исправление: LongLiveUbuntu (всего исправлений: 2)