- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
when {
(defaultCurrency != null) -> {
when {
(currenciesList == null) -> {
currenciesList = mutableListOf(defaultCurrency)
}
(currenciesList?.isEmpty() == true) -> {
currenciesList?.add(defaultCurrency)
}
else -> {
if (currenciesList?.contains(defaultCurrency) == false) {
defaultCurrency = currenciesList?.first()
}
}
}
}
else -> {
when {
((currenciesList == null) || (currenciesList?.isEmpty() == true)) -> {
throw IllegalArgumentException("Default currency and list of currencies from terminal configuration are empty")
}
else -> {
defaultCurrency = currenciesList?.first()
}
}
}
}
Что-то сишарпное.
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. возвращает a, если оно не null, иначе возвращает b.
https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/nullable-types/
• Синтаксис T? является сокращением Nullable<T>. Эти две формы записи являются взаимозаменяемыми.
• Используйте оператор объединения со значением NULL, ??, чтобы присвоить значение базовому типу на основе значения типа, допускающего значение NULL:
Короче, совпадает только знак вопроса после имени типа. Всё остальное сделали по-разному.
Плюнул, лучше статическую документацию посмотрю.
https://hackernoon.com/4-things-i-want-to-see-in-python-4-0-85b853e86a88
Про JIT понравилось
//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 — и всё, пиздец.
Он просто отработает с ошибкой, когда эта веточка случится.
А случится она через 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 :)
В реальном же случае (или когда программа своя, и нельзя послать заказчика за изменение ТЗ) со временем обнаружатся новые состояния, которых в изначальном ТЗ не было.
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 головного мозга.
КРЕЩЁНЫЕ ГОВНОМ.
Джавить котлованы.
Дженерики набигают.