@kotlin_lang

Страница 539 из 982
Igor
12.02.2018
18:23:53
Ну да, только хотелось бы что inline - типа как макрос. В общем я понял, спасибо.

Andrey
12.02.2018
23:35:24
Он и так "типо как макрос", инлайнится же. Просто не везде и не все

Google
Bogdan
13.02.2018
01:19:16
Он и так "типо как макрос", инлайнится же. Просто не везде и не все
я пробывал декомпилировать сдудия зависла

Sergey
13.02.2018
09:54:41
А почему нельзя сделать inline suspend функцию, которая вызывает suspend лямбды?
разве просто inline фукнции с параметрами лямбдами нельзя использовать с suspend лямбдами? пример - forEach из stdlib. или есть какой то смысл делать именно inline suspend f(g: suspend () -> Unit)?

Sergey
13.02.2018
09:56:11
аа. понял. спасибо

DarkMentat
13.02.2018
10:34:40
все еще ребят, простите что задалбываю, но я так и не догнал

есть в идее рулы линта



для котлина тоже

кто-то писал для них кастомные варнинги?

а именно варнинги про hardcoded string

Sergey
13.02.2018
10:36:36
@KirillTim нет ли какой информации о поддержке suspending констркуторов? не планируется в будущем?

https://github.com/Kotlin/kotlin-coroutines/issues/52 тут Роман писал что в ближайшем будущем не планируется. Не изменилось?

Stan
13.02.2018
10:43:05
Было бы неплохо

Google
Sergey
13.02.2018
10:48:52
если нужно сделать что то асинхронное в констркуторое, что требует ссылку на еще не до конца созданный инстанс

в целом можно заменить на класс с констркутором без параметров и отдельно написать фабирку

Vladimir
13.02.2018
10:52:07
@KirillTim нет ли какой информации о поддержке suspending констркуторов? не планируется в будущем?
Мне кажется, это как-то плохо совмещается с тем, как обычно ведёт себя JMM. Если недоделанный объект будет становиться виден другим потокам, могут возникнуть большие проблемы с потокобезопасностью.

Sergey
13.02.2018
10:52:47
вы и так можете из констркутора вызывать что угодно и передать this, тут особо ничего не меняется...

а конеретно suspend констркуторы видимо как раз и будут генерироваться в фабирки, т.е. не будут являться констркуторами с точки зрения jvm

Quantum Harmonizer
13.02.2018
10:54:58
Стоп, а зачем это нужно? Можно же делать ленивые саспенд-геттеры, это идейно правильнее.

Sergey
13.02.2018
10:59:50
если по назначению: то например val service = MyService() который в констркуторе ждет например соединения с бд

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

т.е. создаем некий объект заготовку, напонляем его значениями, и только потом вызываем инициализацию

Quantum Harmonizer
13.02.2018
11:02:24
т.е. создаем некий объект заготовку, напонляем его значениями, и только потом вызываем инициализацию
Не знаю ситуации, но может стоит сделать инициализацию ленивой, по запросу?

Sergey
13.02.2018
11:05:25
не вижу, где здесь может быть полезен suspend
class MyDbConnection suspend (dbHost: String) { val connection = connectDb(dbHost) } fun use() { launch { val conn = MyDbConnection() con.query() } }

MyDbConnection() - засыпает внутри, на время соединения с бд

Quantum Harmonizer
13.02.2018
11:06:07
MyDbConnection() - засыпает внутри, на время соединения с бд
пусть он засыпает при первом запросе

Sergey
13.02.2018
11:07:34
пусть он засыпает при первом запросе
тогда вот такое будет работать неверно fun use() { launch { val conn = MyDbConnection() println("connnected") con.query() } }

Не знаю ситуации, но может стоит сделать инициализацию ленивой, по запросу?
abstract class Buildable { suspend fun waitBuild() = TODO(suspendCorutine) fun build() = TODO(resumeCorutine) } class MyObj(): Buildable { lateinit var x: String val y: String suspend init { waitBuild() y = "Hello, $x" } } fun sample() { val stub = MyObj() stub.x = "username" stub.build() println(stub.y) // Hello, username }

Quantum Harmonizer
13.02.2018
11:12:29
тогда вот такое будет работать неверно fun use() { launch { val conn = MyDbConnection() println("connnected") con.query() } }
если соединение оборвётся в процессе, тогда тоже будет «работать неправильно»

Gleb
13.02.2018
11:12:37
Привет! Почему при IS не происходит автокастинг .dropWhile {it.cause is StatusRuntimeException} И приходится дальше все равно оборачиваться && (it.cause as StatusRuntimeException)

Google
Quantum Harmonizer
13.02.2018
11:13:20
Привет! Почему при IS не происходит автокастинг .dropWhile {it.cause is StatusRuntimeException} И приходится дальше все равно оборачиваться && (it.cause as StatusRuntimeException)
потому что нет гарантии, чт cause каждый раз будет возвращать один и тот же объект. Стоит вытащить cause в локальную переменную.

Sergey
13.02.2018
11:13:30
если соединение оборвётся в процессе, тогда тоже будет «работать неправильно»
ну это же просто пример. там не обязательно соединение с бд, может быть и ресурс который не обрывается. например данные картинки: class Image suspend(imageUrl: String)

Gleb
13.02.2018
11:14:08
it.cause is StatusRuntimeException && (it.cause as StatusRuntimeException) Разве после && нет гарантии уже?

Quantum Harmonizer
13.02.2018
11:14:10
ну это же просто пример. там не обязательно соединение с бд, может быть и ресурс который не обрывается. например данные картинки: class Image suspend(imageUrl: String)
тут имеет смысл фабричный метод, который сначала засуспендится, а потом, получив данные вызовет конструктор

it.cause is StatusRuntimeException && (it.cause as StatusRuntimeException) Разве после && нет гарантии уже?
нет, потому что getCause во второй раз может вернуть другой объект

Sergey
13.02.2018
11:14:55
тут имеет смысл фабричный метод, который сначала засуспендится, а потом, получив данные вызовет конструктор
да, это воркэраунд. но нужно писать значительно больше кода если асинхронные данные нужно полжить в val свойства

а если была бы такая фича, то компилятор бы сам это все написал

Gleb
13.02.2018
11:15:16
fucking mutations(

@Harmonizr Спасибо все ясно!

Quantum Harmonizer
13.02.2018
11:16:17
да, это воркэраунд. но нужно писать значительно больше кода если асинхронные данные нужно полжить в val свойства
саспенд-конструкторы противоречат здравой логике, а тем более асинхронный val. Либо конструктор отработал, либо нет. В момент саспенда получится объект шрёдингера, который никому нельзя показывать.

Sergey
13.02.2018
11:16:46
да, но тоже самое происходит и в обычном констркуторе. если this утечет в констркуторе

Quantum Harmonizer
13.02.2018
11:21:37
да, но тоже самое происходит и в обычном констркуторе. если this утечет в констркуторе
Утекание this — это очевидно плохо и ловится статическими анализаторами. Соответственно, suspend-конструкторы — тоже плохо :)

Sergey
13.02.2018
11:22:58
ну правила все те же что и для обычных констркуторов, просто нельзя допускать того чтобы this утекал куда попало. тут ничего не меняется

разница только в том что можно вызывать саспенд функции. с точки зрения понимания все ровно также

еще раз: оснвной бонус в том, что компилятор будет делать нехилые такие преобразования, которые сейчас нужно делать вручуню

Dmitry
13.02.2018
11:57:49
Ребят, подскажите, пожалуйста, где внятно (можно на английском) почитать про обработку ошибок при использовании корутин?

Andrew
13.02.2018
12:01:12
Собственно, если suspend-конструктор можно вызывать только в suspend-функциях, то полуготовый объект никуда не утекает. Но если правильно готовить DI, то нужды в конструкторе вызывать suspend-функции практически нет, имхо.

Mikhail
13.02.2018
12:17:03
Я думал, времена, когда модель пользователя сама ходила за собой в бд давно прошли

Google
Sergey
13.02.2018
12:19:08
ну, т.е. если какой то метод di должен что то подождать при предоставлении требуемой зависимости

или речь про то, что объект должен создаваться только когда все его зависимости уже есть?

Andrew
13.02.2018
12:22:21
или речь про то, что объект должен создаваться только когда все его зависимости уже есть?
This. Если делать DI асинхронный самому, можно готовить граф в suspend fun и отдавать в ктор готовые зависимости, если фреймворк, то он сам под капотом об этом думать будет.

Sergey
13.02.2018
12:25:05
This. Если делать DI асинхронный самому, можно готовить граф в suspend fun и отдавать в ктор готовые зависимости, если фреймворк, то он сам под капотом об этом думать будет.
а откуда тогда di узнает что этому объекту нужно? вот например какому то объекту нужна картинка по некоторому урлу, значение котрого определяется только в констркуторе объекта которому эта картинка нужна. или предлагаетсься как раз избегать такого (ценой усложнения кода)?

Sergey
13.02.2018
12:27:49
ну, речь про случай когда нужно зафиксировать значения в val. это можно сделать только в констркуторе (или придется делать временные переменные)

Andrew
13.02.2018
12:34:49
Не до конца понимаю. class ImageView(val url: String) { private var img: Image suspend init { img = loadImage(url) } } fun somewhere() { val view = ImageView("http://example.org/kitten.png") } class ImageView(private var img: Image) suspend fun somewhere() { val img = loadImage("http://example.org/kitten.png") val view = ImageView(img) }

Если в конструкторе надо решать, какую картинку грузить, это опять же скорее всего нарушает SRP (является не основной задачей конструктора, а второй) и стоит вынести наружу -- к примеру, в фабрику картинок.

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

Sergey
13.02.2018
12:45:58
Но как выше давно верно отметили, в качестве быстрого решения можно просто сделать suspend-фабрику, которая будет готовить для конструктора зависимости -- это тот же DI, но в масштабах одной функции, на случай если нет возможности брать и переделывать всех потребителей этого класса.
Вот именно этот случай. Бывают случаи когда в констркуторе есть определнная логика, которая что то раскладывает по private полям создаваемого класса. Если эту логику выносить в отдельную функцию фабрику, то приедтся все private свойства передавать через констркутор. Было бы здорово если компилятор бы сам делал такую функцию.

Sergey
13.02.2018
12:52:53
Но как выше давно верно отметили, в качестве быстрого решения можно просто сделать suspend-фабрику, которая будет готовить для конструктора зависимости -- это тот же DI, но в масштабах одной функции, на случай если нет возможности брать и переделывать всех потребителей этого класса.
class SomeModuleFacade suspend (config: ModuleConfig) { private val service1: Service1 private val service2: Service2 private val service3: Service3 private val serviceN: ServiceN init { // много строк, которые создают и настривают сервисы в зависимости от конфига // причем настройка требуется вызыва каких то suspend функций, // например чтобы предеать сообщение и получить ответ (чтобы не синхронизироваться с блокировкой потока) } fun doSomething() { // тут нужно вызвать все сервисы предавая результат одного в параметры другого } } в качестве воркэраунда конечно же можно сделать internal констркутор куда все эти сервисы передавать, и сделать публичную фабрику. но разве не лучше если компилятор это сделает за нас?

Bogdan
13.02.2018
13:02:26
я надеюсь ты доволен

Andrew
13.02.2018
13:11:54
Dibro
13.02.2018
15:35:56
@KirillTim что такое Kotlin-CR? https://github.com/JetBrains/kotlin/commit/99e731f6a62cdcd38431a7023517dad28a4a0e7c

Sergey
13.02.2018
15:39:52
возможно вот это? https://upsource.jetbrains.com/kotlin/review/KOTLIN-CR-1546

Dibro
13.02.2018
15:41:32
возможно вот это? https://upsource.jetbrains.com/kotlin/review/KOTLIN-CR-1546
оу, и такое есть. а туда только джби могут писать?

Google
Sergey
13.02.2018
15:49:34
Да, наверное
вроде там обсуждают и пулл реквесты с гитхаба, нет? вот например https://upsource.jetbrains.com/kotlin/review/KOTLIN-CR-1722

Kirill
13.02.2018
15:50:27
Sergey
13.02.2018
15:53:20
т.е. оно просто в upsource автоматический из гитхаба копируется?

Kirill
13.02.2018
15:55:21
Думаю что да. Учитывая то, что внешний человек пишет @yole

Страница 539 из 982