
Kevin
25.01.2018
12:26:50
i have this arrayList
[{
"aaa": "#FF7B5CC1",
"bbb": "000",
"ccc": "ghffh"
}]
val arrayList = Arrays.asList<MyModel>(newitem)
I want to replace a value inside it like replace "aaa": "#FF7B5CC1", to "aaa": "#000000"
Dima
let say i have `data class Mymodel(val aaa:String, val bbb:String,val ccc:String)
in my class i have val arrayList = Arrays.asList<MyModel>(newitem) how can i replace the value inside it ?

Dibro
25.01.2018
12:28:27

Konstantin
25.01.2018
12:29:14

Dibro
25.01.2018
12:30:39

Google

Kevin
25.01.2018
12:31:19

Ivan
25.01.2018
13:59:10
слушайие, а в котлине extention функции - это же чисто синтаксический сахар? Т.е. полиморфизм работать не будет?

Kirill
25.01.2018
13:59:30
Не будет.

Igor
25.01.2018
14:02:51

Ivan
25.01.2018
14:03:26
Хм, а как ты хотел?
в смысле как бы я хотел чтобы это работало? или как бы я хотел писать, в плане синтаксиса

Igor
25.01.2018
14:04:22
Ну я не знаю, может ты хочешь что-то типа ext-interface. Что может быть когда-нибудь завезут в виде тайп-классов.

Ivan
25.01.2018
14:06:34
не, у меня последнее время очень часто встаёт вопрос диспатчинга. Например приходит из сети байты, ты их десериализуешь в Object/Serializable, а дальше тебе нужно запихнуть в обработчики типа
onEvent(MySuperClass my) {...}
ну и один из способов который боле-менее выглядит красивым - это на Object повесить дефолтную реализацию onEvent которая, например, просто логирует и на каждый нужный объект ставим нужную нам реализацию и после десериализации вызываем obj.onEvent()
а тут же были ребята которые пилят компилятор котлиновский, интересно, чисто гипотетически на уровне байт кода это реально сделать эффективно?

Руслан
25.01.2018
14:28:12

Ivan
25.01.2018
14:29:43
сорян за джавовый интерфейс

Руслан
25.01.2018
14:31:50
ок, тебе сериализатор на лету новые классы не создает? у тебя же наверно есть какой-то набор классов которые то ожидаешь.
соответсвенно все что хочешь - скастить во что-то Serializable и дальше с ним работать?

Google

Ivan
25.01.2018
14:32:21
ну понятно что можно это сделать на мапе или на паттер-матчинге
но это какая-то простыня же будет, а с экстеншином элегантно )

Руслан
25.01.2018
14:32:46
можно использовать sealed
в будущем тебе внутри поле сделают интовое, и просто будет tableswitch

Ivan
25.01.2018
14:35:00
ну всё-равно, например 10 классов на 5 написаны свои имплементации onEvent, остальные подефолту, то что я предлагаю - это взял написал 6ую и всё работает, а со свичом - написал 6ую и пошёл в мапу/switch и добавил вызов
в эвент дривене, события часто появляются новые

Руслан
25.01.2018
14:37:15
В интерфейс закинуть дефолтную имплементацию?

Ivan
25.01.2018
14:38:23
ну не в сам интерфейс, а тоже экстеншином

Руслан
25.01.2018
14:38:40
ну вообще чем плох when с его default case?

Ivan
25.01.2018
14:39:00
я же написал, добавление в 2 места
если забыл добавить во второй - очень удивляешья почему не работает
ну и если везде так, то копируешь абсолютно одинаковый switch по всем сервисам

Руслан
25.01.2018
14:40:46
у тебя очень быстро меняются требования

Ivan
25.01.2018
14:40:53
в общем, я не говорю что задача не решаема, но идеала пока нет
в смысле? требование одно - писать новый код, не изменяя старый

Vadim
25.01.2018
14:41:41
Ребята, как я могу проверить, что данная переменная ТОЧНО содержит "session_secret"?
val sessionSecret = remoteMessage?.data?.get("session_secret")

Ivan
25.01.2018
14:41:45
это же такой клёвый идеал ооп к которому нужно стремиться

Igor
25.01.2018
14:43:18
А expression-problem разве решена в ооп?

Руслан
25.01.2018
14:43:57
sealed class Event
class AddEvent : Event()
class RemoveEvent : Event()
fun Event.handle() {
when (this) {
is AddEvent -> println("Let's Add")
is RemoveEvent -> println("Let's Remove")
else -> println("Unknown type ${this::class}")
}
}

Google

Dibro
25.01.2018
14:44:05

Руслан
25.01.2018
14:44:14
Я могу сколько хочу добавлять новых типов
Редактировать нужно только тело when

Ivan
25.01.2018
14:44:54

Vadim
25.01.2018
14:47:12
только не все сразу)

Ivan
25.01.2018
14:48:08
Редактировать нужно только тело when
ну так я с этого начал, это понятно, это можно даже без sealed класса, просто напихал функций в мапу и берёшь по классу. Просто это всё требует изменения существующего кода, в то время как с полиморфизмом тебе нужно добавить только реализацию под конкретный класс и всё, точка, больше ничего не нужно, всё работает, никакой регистрации, никакого изменения свича и тому подобного

Руслан
25.01.2018
14:48:50
Окей, значит делаешь интерфейс и погнал.
В чем проблема?

Ivan
25.01.2018
14:49:25

Руслан
25.01.2018
14:49:48
ну для всех твоих ивентов

Ivan
25.01.2018
14:49:55
и?
допустим есть
даже допустим там дефолтная реализация лежит
вот для Вашего случая:
sealed class Event
class IntEvent(val i: Int) : Event()
class StirngEvent(val str: String) : Event()
и далее Вам нужно раскидать это до методов
fun onEvent(val ie: IntEvent) { ie.i + ie.i }
fun onEvent(val se: StringEvent) { print(se.str) }

Dibro
25.01.2018
14:54:19

Ivan
25.01.2018
14:55:00
без сфитча, без мапы и т.п.

Руслан
25.01.2018
14:55:23
даже допустим там дефолтная реализация лежит
interface Event {
fun handle() = println(this::class)
}
class AddEvent : Event {
override fun handle() = println("Add")
}
class RemoveEvent : Event {
override fun handle() = println("Remove")
}
class EditEvent : Event {}

Dibro
25.01.2018
14:55:59
потому что классы используются более чем в одном месте/сервисе/программе

Ivan
25.01.2018
14:56:10

Google

Ivan
25.01.2018
14:56:15

Руслан
25.01.2018
14:56:51
Ну т.е. требований больше чем одно, просто они добавлялись несколько сумбурно.

Ivan
25.01.2018
14:57:17
ну я умею в полиморфизм, я не думал что Вы обо мне так плохо подумаете =)
требование в целом одно, диспатчить события
события по определению - value type
т.е. возвращают только данные

Руслан
25.01.2018
14:58:23
Но "менять код в одном месте" и "потому что классы используются более чем в одном месте/сервисе/программе" не сильно дружат
Иначе бы просто полиморфизм

Dibro
25.01.2018
14:58:48
попробуй с генерацией кода, вроде довольно просто такого достичь
собирать все методы с аннотацией и генерить класс который внутри будет свитчить

Ivan
25.01.2018
14:59:35

Руслан
25.01.2018
14:59:51
Почему бы не sealed использовать? Добавил новый тип - у всех билд сломался пока не добавят обработчик

Ivan
25.01.2018
14:59:54
и через динамическую генерацию байткода

Руслан
25.01.2018
15:00:49
так else не делать и все ок
или тогда ломается то что сервисы не должны меняться при добавлении нового типа?
тогда тут опять противоречие

Ivan
25.01.2018
15:04:32
ну и да, со свичом всё-равно менять код сервиса в более 2х местах

Google

Руслан
25.01.2018
15:05:05
почему?

Ivan
25.01.2018
15:05:33
в смысле просто в 2х местах

Руслан
25.01.2018
15:05:49
одно место - тело when, а второе место?

Ivan
25.01.2018
15:05:58
сама обработка
важна-то сама обработка, всё остальное бойлерплейт
свитч - бойлерплейт

Руслан
25.01.2018
15:06:38
эм, ну это странно. обработка это вызов метода из when?

Ivan
25.01.2018
15:07:22
мапа обработка - это функция
fun onEvent(val ie: IntEvent) { ie.i + ie.i }

Руслан
25.01.2018
15:07:29
почему не делать обработку прям в when?
не вижу в общем тут проблемы

Dibro
25.01.2018
15:08:09
если б все в одну строчку, то да

Руслан
25.01.2018
15:08:42
ну если не в одну - вызвал метод и все. я бы не сказал это это два места

Ivan
25.01.2018
15:08:52
нуууу, там 20 событий, на каждое нетривиальная обработка, это будет свитч на тысячи строк кода

Igor
25.01.2018
15:09:11

Ivan
25.01.2018
15:11:57
короче это всё-равно получается огромная простыня со switch где в каждом сервисе одно и тоже
fun dispatch(val event: Event) {
when (event) {
is AddEvent -> onEvent(event)
is RemoveEvent -> onEvent(event)
is IntEvent -> onEvent(event)
is StringEvent -> onEvent(event)
{... и ещё вагон аналогичных вызовов ... }
else -> println("Unknown type ${this::class}")
}

Руслан
25.01.2018
15:12:21
Визитор может?

Ivan
25.01.2018
15:12:36
омг, визитор подразумевает код в Event

Руслан
25.01.2018
15:12:52
Нет, сча накидаю что я имею в виду)

Ivan
25.01.2018
15:13:09
дабл визитор?