/Tt/bfr / it-юмор :: geek (Прикольные гаджеты. Научный, инженерный и айтишный юмор)

it-юмор geek 
/Tt/bfr,it-юмор,geek,Прикольные гаджеты. Научный, инженерный и  айтишный юмор
Подробнее
/Tt/bfr
it-юмор,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор
Еще на тему
Развернуть
Если я правильно помню, это наоборот, изначально class был создан на основе struct с помощью тонны костылей.
Есть ли резон в применении struct?

Делаю игру в Unity, в целях самообразования и заготовки для последующего проекта, и на моменте заготовки ScriptableObject для хранения перевода строк, сделал отдельный класс который хранит строки с ключом и переводами, так-вот думал делать из него struct или обычный класс. Остановился на классе, так-как не понимаю преимуществ struct и мне лень проверять нормально ли он будет сериализоваться, не будет ли каких-либо подводных камней...
Anorihon Anorihon 20.10.201918:29 ответить ссылка -0.4
Возможно, кэп.

Если вы говорите о C#, то между struct и class есть различие. Грубо говоря, struct - value type, хранятся там, где определены. class - referency type, всегда хранятся в куче, а переменная хранит ссылку (указатель) на объект в куче.

Из этого и возникают различия.
Если вы создаете локальную переменную value типа, то она будет на стеке, а reference type - в куче.
Если вы создаете массив из элементов value типа, то элмент массива будет хранить его целиком, а в случае reference типа будет хранить только ссылки на элементы в куче.
Reference type может быть null, value type - нет.
Reference type в функцию передается по ссылке, value type - копируется целиком.
И так далее.
Спасибо за пояснения.
Да, речь о C#. Если я правильно понял, то главное отличие struct от класса в том что копируется ссылка или объект целиком, верно?


PS: минусаторам комментов - желаю вам по больше подводных камней и ноль помощи во всех начинаниях :)
Опять же по опыту из других языков — выделение в куче всегда хуже, чем выделение на стеке. В других языках можно получить указатель и на стек, тогда полного копирования не будет, равно как и обращения к куче. Ну и невозможность null — это гарантия того, что у тебя всегда будут нужные данные, в случае с ссылкой ты обязан всегда проверять её на нулевое значение. Твое обобщение отличия звучит как-то однобоко. Но опять же — это взгляд со стороны, слушай сотоварищей по языку в первую очередь.
Хорошо, вот как грамотно поступить в моем случае с хранением переводов строк?
Вводные данные:
Язык - C# в рамках Unity
Есть лист/массив в котором хранится список из класса TransStr который хранит строковые переменные - ключ, перевод на рус, перевод на англ и т.д

Вопрос - класс TransStr лучше сделать struct или оставить в виде класса?

Также, сам лист/массив хранится в ScriptableObject, говорю на случай если это имеет значение по вопросу выше
В вашем юнити я ни в зуб ногой.

TransStr - это какое-то стандартное решение? Почему бы вместо того, чтобы в лист класть объекты, у которых есть поле ключа, не положить все это в словарь? Ключ - ключ словаря, а сам объект хранит несколько ссылок на строковые переменные для разных переводов. Это и проще, и быстрее.

Что вы хотите делать с этими TransStr? Они куда-то передаются? Как я понимаю, создается все это один раз.
Вообще, я думаю, разница минимальна. Строки - это ссылочный тип, поэтому что класс, что структура будут хранить просто несколько ссылок на строки с переводом. Также стоит посмотреть на то, как эта вся хрень инициализируется и сделать, как удобнее. Так, к примеру, для создания массива структур, они должны иметь конструктор по-умолчанию.

TL;NR С вероятностью 95%: вообще похуй, храните как хотите, пусть класс остается
Нет, TransStr это мой произвольный класс.
Словарь к сожалению не сериализуется в рамках ScriptableObject (сериализуемый класс/объект в Unity - заточен под работу с Unity потому эффективнее нежели хранение текста в json и подобных), потому шаманю со списком.

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

Спасибо, оставлю класс. Мне было любопытно разобраться что это за Структуры и есть ли смысл их применять к TransStr, из того что узнал - в данном случае без разницы :)
Главное отличие ссылочного типа от типа значения в том, то при создании экземпляра ссылочного типа, память под него выделяется в управляемой куче, а переменная хранит ссылку (ну, фактически. указатель) на него. Экземпляр объекта типа значения выделяется "по месту", переменная хранит его целиком.

Все отличия в поведении являются следствием.
1. Ссылочный тип может быть null, ведь это только указатель. Тип значения не может быть null, ведь он, грубо говоря, весь набор байт, нужный, чтобы хранить объект. Неинициализированным (хранить мусор) он быть не может в принципе, C# этого не допускает.
2. Что происходит при передаче аргумента? Объект копируется в вызываемую функцию. Но в случае объекта ссылочного типа копируется только указатель, а данные как лежали в куче, так и лежат. В случае объекта типа значения, он копируется весь. Правда, есть ref, сейяас есть еще ref return но это другая история.
3. Что происходит при присвоении одной переменной другой? Объект копируется. В случае ссылочного типа копируется только указатель, т.е. две переменные указывают на один объект в памяти. В случае типа значения - происходит копирование. Но есть еще перегрузка операторов, мелкое и глубокое копирование итп.
4. Когда переменная покидает область видимости, она уничтожается. Но в случае с переменными ссылочного типа удаляется только ссылка, а объект остается в памяти, и на него могут указывать еще несколько ссылок. Поэтому и нужен Garbage Collector, чтобы это все удалить. Объект типа значения удалится целиком.

В общем, можно продолжить рассуждения в таком духе, главное - уловить суть. Последний пункт, ИМХО, очень важен. Вообще, ссылочный тип в ряде случаев медленнее, ведь нужно и аллоцировать память, и требуется работа сборщика мусора.

Но вообще, модель памяти шарпа мне кажется очень простой, в отличие от плюсов, где что угодно может быть где угодно, и ебись с этим сам.
Спасибо за детальное пояснение!
Сохраню в заметках, это довольно важные пункты для понимания и грамотного применения Структур и Классов
У меня к вам один простой вопрос. Прежде, чем идти и писать свою, безусловно, мегаохуенную игру на юнити и осваивать язык по комментах на джое, вы не пробовали почитать книжки по C# и .NET? Вы знаете, там все это расписано, и, думаю, сделано гораздо лучше, чем это может сделать какой-то анон из интернетов, который на шарпе давно не писал.

Например:
- Рихтер, CLR via C#. Вроде, годная книга, которая знакомит с устройством всей этой кухни на глубоком уровне. Эту книгу хвалят. Вроде мне тоже ОК.
- Язык программирования C# N и платформа .NET M (разные издания под разные версии). Вроде как книга, ориентированная на читателей с околонулевым опытом в программировании вообще. Не только про шарп, но и про всякие .NET-based технологии (WPF, ASP.NET итп)
- Язык программирования C#. Классика Computers Science. Тут от отца-основателя шарпа, но не читал.
- Сайт https://metanit.com/. Там много по C# вообще и по всяким ASP.NET/WPF/итп в частности. Вроде, обновляется под новые, актуальные штуки и версии.
С чего вы взяли что я не читаю документацию/книги и не смотрю обучающие ролики?
Есть моменты которые объяснены мудрено / вопрос плохо освещен / отсутствует информация по работе в рамках Unity (например, несколько дней потратил на поиск инфы по динамичному обновлению сериализованных списков через кастомный редактор в Unity - такой инфы мало, а то что есть очень хреново или косвенно освящает вопрос) и т.д

Я не говорил что делаю мегаохуенную игру, а наоборот сказал что делаю игру в целях самообучения и заготовки для следующего проекта который уже будет коммерческим и для которого будут учтены все косяки и пробелы в архитектуре заготовки. Мое ЧСВ не на столько завышено чтоб считать поделку мегаохуенным проектом

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

Несомненно комменты на Джое могут быть не лучшим источником информации, но здесь могут найтись люди как вы - которые могут объяснить мудреные моменты или подсказать где можно найти информацию для чайников вроде меня


В любом случае, спасибо вам за ответы и ссылки
Anorihon Anorihon 20.10.201920:54 ответить ссылка -0.1
Ну ладно, извините. В общем, советую почитать "CLR via C#", я думаю, эта книга даст много знаний как о элементах языка, так и о том, как оно все там устроено. В том числе, такая важна я концепция, как value и reference типы там точно разъяснена. А еще есть смежная тема - boxing/unboxing, причина отстрела ног и плохой производительности итп итд.
Спасибо, почитаю
Всё зависит от языка и области применения. Классы — часть ООП, которое где-то считается плохой практикой, а где-то сам язык основан на ООП (ну и ООП бывает разное: как в smalltalk и как в плюсах). Для геймдева сейчас идёт отказ от ООП с классами в пользу ECS со структурами, т.к. игры стали сложными, с сущностями, ссылающимися друг на друга. ООП стал просто мешать в этом случае, принося тормоза и абсолютно никак не следя за ресурсами.
Ну а главное, за что ненавидят классы — это их непредсказуемость, связанная с инкапсуляцией и наследованием. Например, ты попытался сериализовать класс — получил неправильный результат. Стал смотреть функцию сериализации (не знаю, как она устроена в твоём языке, говорю с представлением плюсов), а её нет. Значит, надо искать в каком предке что пошло не так. И с этого момента начинается копание в лапше. Чуть исправил предка — могла сломаться половина потомков, что усложняет поиск проблемы. Ну а в случае со структурами всё приходиться писать и вызывать явно. Да, это делает мир сложнее, поэтому похожие явления называют синтаксической солью, зато код становится безопаснее для будущей поддержки. Проблемы усложнения кода решаются синтаксическим сахаром, который не пытаются натянуть на ООП. Такой сахар безопаснее. Для поддержания ООП приходится придумывать новые костыли вроде «классов-друзей», которые напрочь ломают все преимущества, которые даёт ООП, так как теперь можно снова стрелять себе в ногу. В плюсах и вовсе возникло больше десятка конструкторов. При наличии развитой иерархии классов почти невозможно понять что именно вызовется. Но плюсы и не являются хорошим ООП.
В случае с более простыми языками (типа си) не нужно поддерживать парадигму ООП, поэтому эти языки пробуют новые технологии. В ООП тоже вводятся новые ограничения, держащие его на плаву, точно так же — за счёт создания новых, более строгих языков. И с больш́им количеством задач он по-прежнему справляется неплохо. Ну а пытаться найти преимущества не-классов в языках, прибитых к классам (типа java, C#) бесполезно, кмк. Разработчики языка попросту не будут давать таких преимуществ, а от будущих проблем сбежать всё равно не получится. Хочешь понять преимущества структур — пострадай от классов, а затем научись языку с другой идеологией (например, с типажами). Выбирать приходиться не между плюсами одного и другого, а между минусами.
Я понимаю что классы это производные от структур, и благодаря комментам, вроде как понял что есть отличие в передаче ссылки или самого объекта, и в том что Структуры обязуются заполнять все переменные (отсутствие null).
Но все еще до конца не понимаю как будет грамотно поступить с хранением переводов строк. Судя по вашему комменту, если я правильно понял, то мне стоит забить на структуры в рамках C#
То, что я расписал выше характерно (насколько я знаю) только для C# (возможно, других CLR) языков и JVM-языков.
Хейтер ООП детектед.
ECS и ООП - это вообще вещи ортогональные, которые могут спокойно сосуществовать, более того, первое зачастую из второго делается.

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

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

З.Ы. В C++ структуры и классы - same shit.
З.З.Ы. Пишу на Си, и, знаете, ООПа (плюсового) бывает очень не хватает. Например, конуструкторов-деструкторов, чтобы делать RAII. Или полиморфизма. Например, модули ядра Linux реализуют некую пародию на полиморфизм методами Си, храня в структурах указатели на методы.
> Хейтер ООП детектед
Да, есть такой грех. Я понимаю, что связано это с тем, что я не могу удержать всю иерархию классов в голове долгое время, поэтому не призываю к его уничтожению, но и замалчивать его недостатки не собираюсь.
> ECS из ООП зачастую делается
Не правда. Я знаком с преимущественно не ООП-решениями, это зависит от используемого языка.
> вещи ортогональные
ECS чужеродна для ООП. В идеальном мире ООП никаких таких систем нет. Это не мешает построить ECS поверх ООП, ведь мы выбираем лучшие решения, даже если они противоречат основной идеологии. И тем не менее, с точки зрения ООП это будет костылём.
> в си не хватает плюсового ООП
В плюсах мне не хватало несовместимых с С++ фич из си, но да — pure C очень слаб, из-за чего я с него и ушёл, но отнюдь не на плюсы (с которых я ушёл в своё время на си).
> конструкторов-деструкторов
Существуют не ООП-реализации конструкторов-деструкторов. В случае си это будут не самые приятные goto + new_* + free(*). В случае типажей проблем нет вообще — там есть конкретный new (похожий на си-стиль), перестроение типов и автоматическое освобождение по деструктору. RAII в плюсах — собственно костыль для реализации идеологии владения. Но хороший костыль. Был бы он ещё обязательным к соблюдению…
> в области функциональщины
Почти все языки пришли в функциональщину, даже С++. Кто-то обязательно, кто-то опционально. Даже си его со времён создания поддерживает в каком-то виде (как раз благодаря отсутствию ограничений вроде ООП).
> новое и интересное
Типажи и владение, никакой связи с функциональщиной, никакого ООП. И таких языков вроде как хватает. ООП — всего лишь модификация над процедурным программированием, как и всё, что когда-либо придумали.
> кастрированный вариант нормальных ЯП
парадокс блаба?
> не устраняет необходимости думать мозгом
Но пытается уменьшить, иначе в чём смысл? А если концепция приносит больше проблем, чем решает — значит надо искать замену (для конкретного места, которую можно потом сравнить и в других местах, вытесняя старую)
Я не призываю свергнуть ООП, я призываю не обожествлять его в рамках всех языков.
Хм, я, кажется, понял.
Вы говорите об ООП, как о парадигме, может, даже об ООП-мышлении (верно?), я говорил об ООП чисто как о языковой фичи в рамках ее реализации в существующих ЯП (в основном, С++/Java/C#, немного питон), которая может так или иначе структуировать код. Скорее всего, я был некорректен в терминологии.

> Почти все языки пришли в функциональщину, даже С++
Напихали лямбд и страшных темплейтов, типо bind, и думают, что у них ФП? Особенно весело это во всех вебах и джавоскриптах, где типо дрочат на ФП и на лямбды, а толку как-то не много. Я тут больше за мощную систему типов, типо как в хаскеле, но я сам еще не осилил всё. А есть еще Irdis, там вообще огонь, кажется.

> Типажи и владение, никакой связи с функциональщиной, никакого ООП. И таких языков вроде как хватает.
Типажи? Вы про trait (трейты)? Трейты и владение... Как-то очень сильно напоминает Rust. А где есть еще, если вы говорите, что таких языков хватает?

> Но пытается уменьшить, иначе в чём смысл? А если концепция приносит больше проблем, чем решает
Я вижу это так. Вы можете засунуть метод туда, где храните данные. Часто, это бывает очень полезно (ведь даже в Си затаскивают на костылях). Вы можете сделать наследование, чтобы реализовать какие-то новые или переопределить старые методы, добавить всяких данных. Это тоже может быть полезно. Ну, на этом я ООП заканчиваю и не занимаюсь каким-то фанатизмом. Если применение этих языковых средств позволяет мне упростить код, я их применяю. Если нет - значит, в этом месте я буду писать иначе, чтобы это было лучше. Если встает вопрос, к примеру, Складк.ДобавитьТовар() или Товар.ДобавитьНаСклад() (пример утрированный, да), значит что-то где-то пошло не так и ваша ООП-модель хуевая. Что касается лапши наследования, то выход - пиздить. Пиздить ногами. Отсутствие ООП не сильно помогает говнокодерам не говнокодить.
Да, как о парадигме, которую нужно протащить на весь язык, выкинув всё остальное (или ещё хуже — как С++ попытаться приделать бездумно к классам).

> мощную систему типов как в хаскеле
тебе следует попробовать раст, он взял систему типов преимущественно от хаскела, но не так жесток в плане обучения. Если есть такое желание, конечно. Хаскел я одолеть не смог.

> Rust
да, раст

> ещё … трейты
D, Dart, Ruby, Swift, Haxe, Python… ой, они все реализуют ООП. Прошу прощения, сохранить трейты с выкидыванием ООП никто кроме раста не решился, я был уверен в обратном. Каюсь, не проверял, когда слышал такую мысль.

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

> наследование
наследование с инкапсуляцией как раз и даёт новые проблемы. Если удаётся сладить с ним, то ничего плохого в нём нет. В том же расте подобие наследования есть (в рамках дженериков и в си-стиле, то есть явный вызов метода «предка» в виде члена структуры), но опять же — оно возникло как «структура-в-структуре», ООП просто реализует наследование в каком-то виде.

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

> не занимаюсь фанатизмом
коллеги могут всё испортить

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

В самом факте существования ООП как инструмента я ничего плохого не вижу — без инструментов слишком уныло жить, но лично я предпочту другие, это уже субъективно. Просто нельзя называть этот инструмент идеальным, как и любой другой (я об ООП-фанатиках), всегда нужно называть и минусы (а их для ООП обычно замалчивают).
Только зарегистрированные и активированные пользователи могут добавлять комментарии.
Похожие темы

Тренды

Похожие посты
One morning you wake up find out you have access to God’s developer console. What’s the first thing you do with this power?
Discussion
♦ 154 +	W 479	& Share
^ BEST COMMENTS ▼
I like forks • 5h
hehe3301 • 7h
sudo rm -rf oceans/*/contents/
*.plástic
sudo rm -rf people/*/*.cáncer sudo rm -rf v
подробнее»

it-юмор geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор без перевода it humor geek it юмор

One morning you wake up find out you have access to God’s developer console. What’s the first thing you do with this power? Discussion ♦ 154 + W 479 & Share ^ BEST COMMENTS ▼ I like forks • 5h hehe3301 • 7h sudo rm -rf oceans/*/contents/ *.plástic sudo rm -rf people/*/*.cáncer sudo rm -rf v
¿i
OR IS IT TESTING ME?
Й