Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that can not (non-null references). For example, a regular variable of type String can not hold null:
var a: String = "abc"
a = null // compilation error
To allow nulls, we can declare a variable as nullable string, written String?:
var b: String? = "abc"
b = null // ok
print(b)
Safe Calls
Your second option is the safe call operator, written ?.:
val a = "Kotlin"
val b: String? = null
println(b?.length)
println(a?.length)
This returns b.length if b is not null, and null otherwise. The type of this expression is Int?.
Попробовал онлайн-версию. Редактор ублюдочный: кнопка «Run» налезает на текст, кококоторый я набираю, так что ничего не видно; автокомплит только мешает.
А почему, когда я пытаюсь выполнить команду «py -4 hello.py», мне отвечают, что requested Python version (4) not installed? Где его можно скокококочать?
Ты что! Тебя же за это заклюют! Скажут, что это как в сишке или в ещё каком-нибудь языке для калькуляторов 70-х годов. Надо, чтобы выглядело современно: с лямбдами, с шаблонами...
Именно поэтому я за «D»: благодаря «Uniform Function Call Syntax» там вообще не нужно создавать никаких классов, чтобы использовать «fluent interface». Код "Hello, world!\n".printf() там тупо вызовет printf("Hello, world!\n").
Тут больше подойдёт if (currenciesList?.isEmpty() ?: true).
Нам же нужно вернуть true в двух случаях:
1. currenciesList == null
2. currenciesList.isEmpty()
currenciesList?.isEmpty() вернёт либо true, либо false, либо null. Эт наверно чтоб null в false превратить, хотя Котлин наверное всё равно null считает ложью.
Вот кстати не люблю эту питушню с состояниями/характеристиками.
Постоянно приходится думать на пустом месте. Ну то есть тут ни проектирования, ни алгоритмов нет, только пердолинг и отладка.
Главный пример - питушня с битами у крестовых потоков. Их там четыре, и без бутылки во всех кобенациях не разберёшься.
Хуже только проверка характеристик в своём коде. Сначала это true/false, потом какой-нибудь enum или набор флагов. Оказывается, что характеристики полностью ни независимы, ни зависимы - хотя, значения декартово перемножаются, но не совсем. Какие-нибудь гендеры, например.
Сначала в коде появляются сложные условия, специфицирующие определённое подмножество объектов, например, мужчина-гей, в прошлом бывший женщиной.
Потом рождаются хелперы на частые частные случаи, чтобы не ошибиться в записи условия.
Потом оказывается, что надо ввести ещё несколько состояний, и весь код придётся перечитать. Стоит проверить все условия "male" и вставить в часть из них "f2m", в часть - "m2f", где-то оставить как было. Например, в мужской туалет можно пускать (male || f2m), а к психологу в мужские группы по разбору проблем из детства - (male || m2f), в клуб угнетателей - только male. Особо тщательно придётся проверять условия вида "все остальные". Ведь теперь "!male" - нифига не бабы, теперь это 50 оставшихся гендеров.
И заранее можно только не допускать условия вида "все остальные".
Но всё равно, всё так же придётся пересматривать все условия на подмножества. И ничего не поделаешь: если б знали все эти категории и подмножества - сразу бы спроектировали программу с учётом них, а так любая новая категория - непредсказуемая для программиста питушня.
Адово плюсую. Особенно выбешивает рассинхронизация состояний, хуже которой только черви-пидоры.
Буквально ня днях столкнулся: один кусок думал, что модуль может находиться либо в состоянии A, либо в B — и, естественно, делал проверку «state != A». А другой кусок взял да перевёл состояние в C — и всё, пиздец.
> стек состояний
Ну это всех проблем не решает... Вдруг эта котодевка-с-хуем изначально такой родилась?
Имхо, тут нужна обёртка с кучей bool'овских методов. И все проверки должны идти только через неё. Тогда всё это говно хотя бы не будет размазано тонким слоем по всему коду. В одном месте можно будет поменять на стек или что-то ещё.
Пойдём по пути композиции и ассоциации. Вынесем гендер в enum, а для понимания анатомических нюансов сделаем метод getDick(), который возвращает или инстанс хуя, или null
Что-то мне кажется, что эта штука только чуть-чуть облегчит страдания программиста.
Были, скажем, папка для исполняемых файлов и папка для неисполняемых файлов. А потом ввели папку для временных файлов.
Два хелпера "это исполняемый", "это не исполняемый" помогут только инкапсулировать способ представления состояния (число/стек/подгрузка из интернетов), а в коде всё равно придётся исправлять на "это временный" случайные проверки.
Сделать много хелперов не получится: либо запутаешься в их количестве, либо какую-то характеристику из будущего не уловишь. Можно создать по одному хелперу на одну проверку (именовать по номерам строк кода), но введение нового состояния может расщепить проверки в местах, где одна проверка работала для более одного файла.
Я же писал, что они ни независимы, ни зависимы. Стек или кортеж уместны для случая, когда работает декартово произведение множеств. Каждый элемент стека/кортежа всё равно рано или поздно примет несколько новых состояний.
* мужик
* мужик-бисексуал
* мужик-бисексуал, бывший мужиком-натуралом
* мужик-транссексуал-бисексуал, бывший бабой-лесбиянкой, а ещё раньше - полигамной бабой-любительницей транссексуалов m2shemale
1 .Стеком можно эффективно описать становление транссексуала, но оттенки его ориентации придётся вводить как отдельные состояния.
2. Опять же, от переписывания кода проверки условий стек не спасёт. Как ни крути, в традиционном туалете будет важно последнее состояние, а у психолога - первое, второе, ... или все вместе взятые. Ещё и векторную питушню придётся сравнивать. Царского пирфоманса не дождёшься. Или у тебя int гендеров, битовые маски и свичи, или цикл по итераторам std::list 🙂
Если есть ТЗ, подписанные документы и сроки сдачи проекта, программа написана с нуля, то проблемы вообще нет. Хреначим указанные в ТЗ состояния, сдаём проект и прощаемся с заказчиком.
В реальном же случае (или когда программа своя, и нельзя послать заказчика за изменение ТЗ) со временем обнаружатся новые состояния, которых в изначальном ТЗ не было.
совершенно очевидно что код писал пидор
не пидор бы либо сделал лист всегда НЕ нулевым и проверял бы только пустоту
либо сделал бы такой алгоритм чтобы для пустого и непустого листа он работал бы одинаково
val currenciesList = arguments?.getStringArray(EXTRA_CURRENCI ES_LIST)?.toMutableList()
?: mutableListOf()
val defaultCurrency = arguments?.getSerializable(EXTRA_CURRENC Y) as? String
?: currenciesList.firstOrNull()
?: throw IllegalArgumentException(
"Default currency and currencies list are empty"
)
if (currenciesList.contains(defaultCurrency ).not())
currenciesList.add(defaultCurrency)
"Kotlin" довольно молодой езыг, я вот например до сих пор не знаю, как звать погромистов на "Kotlin". Котлинеры? Котлинисты? Котлинерята? Котлинята? Котлинеристы? Котлята? Котлеты? Котлы?
Что-то сишарпное.
In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that can not (non-null references). For example, a regular variable of type String can not hold null:
To allow nulls, we can declare a variable as nullable string, written String?:
Safe Calls
Your second option is the safe call operator, written ?.:
This returns b.length if b is not null, and null otherwise. The type of this expression is Int?.
Я же говорил, «Кокококотлин».
Ещё есть оператор as?, который возвращает null, если ничего не получилось.
И оператор !!, который кидает исключение, если выражение слева от него равно null.
https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/nullable-types/
• Синтаксис T? является сокращением Nullable<T>. Эти две формы записи являются взаимозаменяемыми.
• Используйте оператор объединения со значением NULL, ??, чтобы присвоить значение базовому типу на основе значения типа, допускающего значение NULL:
Короче, совпадает только знак вопроса после имени типа. Всё остальное сделали по-разному.
пройди kotlin koans
https://kotlinlang.org/docs/tutorials/koans.html
через час будешь знать язык
Плюнул, лучше статическую документацию посмотрю.
https://hackernoon.com/4-things-i-want-to-see-in-python-4-0-85b853e86a88
Про JIT понравилось
А phyton есть?
Кстати, что будет если написать if (currenciesList?.isEmpty()) ? Что будет если currenciesList==null?
//Your code for nonNull empty list
}
Хорошая вещь же - fluent interfaces. Луговский одобряет.
https://en.wikipedia.org/wiki/Fluent_interface
https://martinfowler.com/bliki/FluentInterface.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1585.pdf
Отклонили, потому что испугались, что это приведёт к путанице.
но как только нужна функция, которой в них нет, начинается цирк с прототипами-миксинами или, упаси боже, с compose и partial.
Держи.
Нам же нужно вернуть true в двух случаях:
1. currenciesList == null
2. currenciesList.isEmpty()
Постоянно приходится думать на пустом месте. Ну то есть тут ни проектирования, ни алгоритмов нет, только пердолинг и отладка.
Главный пример - питушня с битами у крестовых потоков. Их там четыре, и без бутылки во всех кобенациях не разберёшься.
Хуже только проверка характеристик в своём коде. Сначала это true/false, потом какой-нибудь enum или набор флагов. Оказывается, что характеристики полностью ни независимы, ни зависимы - хотя, значения декартово перемножаются, но не совсем. Какие-нибудь гендеры, например.
Сначала в коде появляются сложные условия, специфицирующие определённое подмножество объектов, например, мужчина-гей, в прошлом бывший женщиной.
Потом рождаются хелперы на частые частные случаи, чтобы не ошибиться в записи условия.
Потом оказывается, что надо ввести ещё несколько состояний, и весь код придётся перечитать. Стоит проверить все условия "male" и вставить в часть из них "f2m", в часть - "m2f", где-то оставить как было. Например, в мужской туалет можно пускать (male || f2m), а к психологу в мужские группы по разбору проблем из детства - (male || m2f), в клуб угнетателей - только male. Особо тщательно придётся проверять условия вида "все остальные". Ведь теперь "!male" - нифига не бабы, теперь это 50 оставшихся гендеров.
И заранее можно только не допускать условия вида "все остальные".
Но всё равно, всё так же придётся пересматривать все условия на подмножества. И ничего не поделаешь: если б знали все эти категории и подмножества - сразу бы спроектировали программу с учётом них, а так любая новая категория - непредсказуемая для программиста питушня.
Буквально ня днях столкнулся: один кусок думал, что модуль может находиться либо в состоянии A, либо в B — и, естественно, делал проверку «state != A». А другой кусок взял да перевёл состояние в C — и всё, пиздец.
Именно потому я за кококококтлин
см енумы и sealed классы
последнее так прямо птрнмчтнг из сами знаете откуда
Он просто отработает с ошибкой, когда эта веточка случится.
А случится она через 3 месяца на продакшене у клиента. И это правильно! К чему заранее решать проблемы?
Главное, в установке «Therac» не использовать языки типа «Питона».
Кстати, в «PHP» до версии 5.4 можно было вызывать break с переменным аргументом:
http://php.net/manual/ru/control-structures.break.php
Именно поэтому я за «PHP».
>А другой кусок взял да перевёл состояние в C
Finite State Machine?
А вот черви-пидоры — ДЕЙСТВИТЕЛЬНО огромная проблема.
По злоебучести примерно соответствующая уровню гномов-хуекрадов.
> По злоебучести примерно соответствующая уровню гномов-хуекрадов.
сочувствую тебе, чувак(
Кстати, черви не могут быть пидорами
Они гермофродиты, как наш Стертор
Угу. Причём засунуть все переходы в одно место не получится — слишком много разнородного говна.
Ну это всех проблем не решает... Вдруг эта котодевка-с-хуем изначально такой родилась?
Имхо, тут нужна обёртка с кучей bool'овских методов. И все проверки должны идти только через неё. Тогда всё это говно хотя бы не будет размазано тонким слоем по всему коду. В одном месте можно будет поменять на стек или что-то ещё.
Были, скажем, папка для исполняемых файлов и папка для неисполняемых файлов. А потом ввели папку для временных файлов.
Два хелпера "это исполняемый", "это не исполняемый" помогут только инкапсулировать способ представления состояния (число/стек/подгрузка из интернетов), а в коде всё равно придётся исправлять на "это временный" случайные проверки.
Сделать много хелперов не получится: либо запутаешься в их количестве, либо какую-то характеристику из будущего не уловишь. Можно создать по одному хелперу на одну проверку (именовать по номерам строк кода), но введение нового состояния может расщепить проверки в местах, где одна проверка работала для более одного файла.
* мужик
* мужик-бисексуал
* мужик-бисексуал, бывший мужиком-натуралом
* мужик-транссексуал-бисексуал, бывший бабой-лесбиянкой, а ещё раньше - полигамной бабой-любительницей транссексуалов m2shemale
1 .Стеком можно эффективно описать становление транссексуала, но оттенки его ориентации придётся вводить как отдельные состояния.
2. Опять же, от переписывания кода проверки условий стек не спасёт. Как ни крути, в традиционном туалете будет важно последнее состояние, а у психолога - первое, второе, ... или все вместе взятые. Ещё и векторную питушню придётся сравнивать. Царского пирфоманса не дождёшься. Или у тебя int гендеров, битовые маски и свичи, или цикл по итераторам std::list 🙂
В реальном же случае (или когда программа своя, и нельзя послать заказчика за изменение ТЗ) со временем обнаружатся новые состояния, которых в изначальном ТЗ не было.
1) лист пустой
2) лист не пустой
3) лист равен нул
совершенно очевидно что код писал пидор
не пидор бы либо сделал лист всегда НЕ нулевым и проверял бы только пустоту
либо сделал бы такой алгоритм чтобы для пустого и непустого листа он работал бы одинаково
val currenciesList = arguments?.getStringArray(EXTRA_CURRENCI ES_LIST)?.toMutableList()
?: mutableListOf()
val defaultCurrency = arguments?.getSerializable(EXTRA_CURRENC Y) as? String
?: currenciesList.firstOrNull()
?: throw IllegalArgumentException(
"Default currency and currencies list are empty"
)
if (currenciesList.contains(defaultCurrency ).not())
currenciesList.add(defaultCurrency)
Fluent interface головного мозга.
КРЕЩЁНЫЕ ГОВНОМ.
Джавить котлованы.
Дженерики набигают.