Как стать автором
Обновить
16
0
Журат Максим @ChessMax

Пользователь

Отправить сообщение

В Dart нет специального синтаксиса для объявления интерфейсов. Любой класс может действовать как интерфейс, и другой класс может его реализовать с implements:

Строго говоря это не совсем так.

Спасибо за статью.

Вы переизобрели MobX) Читая статью думал, будет ли computed, но не увидел (жаль). На самом деле с пользовательской точки зрения это намного удобнее (хотя свои минусы тоже есть). Вместо кучи combineN и RebuilderN был бы один ComputedValue и Rebuilder. Потому, что постоянно указывать и менять цифры, прописывать для всего типы и все это вручную, ну такое... "Продать" относительно Stream и rxdart конечно получилось, но сравнивать, на мой взгляд, нужно не с ними, а с MobX и его аналогами, и возможно даже с Riverpod.

  1. StreamController, через который предполагается посылать обновления в Stream, требует вызова dispose(), а также имеет переусложнённый синтаксис: Stream и StreamController это два разных объекта.

Строго говоря у StreamController -а нет метода dispose.

В подписчик передаётся значение на момент обновления Value через сеттер, а не на момент вызова подписчика, в ряде случаев это важно.

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

такое поведение можно отключить, задав параметр distinctMode = false:

Наверное лучше было бы использовать предикат? В таком случае возможности были бы шире.

Пример с combine2 не компилируется. Зачем делать в CombinedValueSubscription метод отмены с типом Future, если ассинхронность не используется?

При этом теряется возможность обработки ошибки в Stream (в Value эта концепция отсутствует), но можно через параметр errorBuilder задать преобразование ошибки в значение Value (например в null, если underlying тип nullable).

Если использовать тип Either, то можно не терять возможность обработки ошибок.

final startSw = Stopwatch()..start();

Создавать новый экземпляр Stopwatch на каждый вызов notify несколько накладно.

scheduleMicrotask(() async { // unawaited

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

//! There is a potential problem in multiple entering paused state

Ну такое стоило сразу поправить, тем более, что это совсем не сложно сделать.

@override R get value => transformer(origin.value);

Очевидно, что transformer может быть накладен для вычисления, и лучше кэшировать значение.

Примечателен тот факт, что Value сам по себе не требует вызова dispose(), он штатно утилизируется сборщиком мусора.

Вы в нескольких местах что-то подобное пишете, но по факту это не совсем правильно. По-хорошему ваш Value так же должен предоставлять метод dispose или его аналог, т.к. во-первых, чтобы можно было отписаться от все подписок, с текущим апи это сделать нельзя. Во вторых наследники этого класса используют, например Timer, который тоже никак не остановить, насколько я понял и он будет тикать, хотя уже может быть давно не нужен. Просто если тот же StreamController использовать по аналогии с вашими классами, то мы так же не обязаны вызывать dispose и будет плюс-минус такое же поведение, что и вас.

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

То что есть порядок вычислений и не все считается, не говорит, о том, что таблица истинности не используется. Вот, например, есть выражение a && b && c. Мы вычислили значение a и оно равно false. Воспользовавшись таблицей истинности и тем свойством, что считать все остальное не нужно вернули результат сразу. Оперировать таблицей в общем случае, это не значит, что нужно посчитать сначала все операнды. И вот здесь не соответствие между не оперирует, хотя на самом деле вполне оперирует. Мне кажется без таблицы истинности (явно или не явно) нельзя реализовать эти операторы, т.к. таблица истинности это и есть определение операции, просто в табличной форме, разве нет?

Да это понятно. Просто фраза "не оперируют таблицей истинности" звучит странно (но может быть я не прав), как будто бы при вычислении она не используется, хотя она используется. И то что первый или второй операнды могут не вычисляется, это (опять, как мне кажется) не говорит, о том, что таблица истинности не используется. Это лишь говорит, что при вычислении выражения используются свойства логических операций, позволяющие не выполнять ненужных операций.

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

Можно вот этот момент разъяснить? Если результат совпадает, то это значит, что они оперируют таблицей истинности, разве нет? Или что здесь имеется ввиду?

Может быть подойдут сервисы по типу клавагонок ? Небольшой спортивный азарт, кастомизация машинок, все лучше "бессмысленного" (с точки зрения ребенка) перепечатывания текста с экрана? Кроме того можно тренироваться на своих текстах. Согласен, не идеально, но хоть что-то?

Спасибо за совет. Смотрю нескольких, но ощущение, что толку от этого нет. Своего рода развлекательный контент. Запомнить что-то малореально.

Но играть сильнее они почему то не стали, а вот видеть мат – стали точно лучше. Парадокс!

Вот это очень интересный момент. Тоже за собой такое замечаю. Задачи решаются относительно неплохо. А вот качество игры никакущее. И как это исправить не особо понятно. А что на ваш взгляд наиболее сильно влияет на улучшение именно качества игры в целом?

Более того я потеряю премию

и

денег мне и так хватает)

Мне кажется или эти фразы не стыкуются? Если деньги вас не мотивируют, то вам должно быть глубоко фиолетово на все эти цели и выполнили вы их или нет. Или я чего то не понимаю?

Подобрать хорошую задачу для тестового задания очевидно непросто. И так же очевидно, что эта задача явно не самый худший вариант для тестового (плюс в том, что не очень объемная задача и судя по всему из реальной жизни). С другой стороны я не уверен, что джун сам сможет справиться с ней (хотя может я и не прав). Ну а сеньору наверное вообще не стоит давать тестовое... (имхо).

− чтобы текст начал обрезаться с многоточием, элементу текста надо дать возможность занимать меньше отведённого под полный текст места без ошибки RenderFlex overflowing , то есть применить констрейнт

Чтобы текст начал обрезаться нужно тексту задать ограничение по ширине (это легко проверить, засунув текст в SizedBox). Так же нужно понимать как работает лейаут у Row/ Column. Оверфлоу возникает не у текста, а у row. Row спускает unbound (от нуля до бесконечности) ограничения своим детям. Т.е. говорит тексту будь любых размеров, вне зависимости от ограничений row (от ширины row). И если по итогу ширина текста превышает ограничения row, то и происходит оверфлоу. Таким образом текст не обрезается из-за того, что от row пришли unbound ограничения. Вот и все. Крайне полезно разобраться с тем как работают лейаут и ограничения во флаттер (можно сделать по вот этой статье и своим экспериментам или чтением исходников). И тогда жизнь станет значительно проще)) Соответственно, если знаешь как эта система работает, то сделать так, чтобы она работала как тебе нужно обычно не сложно...

Как-то вы довольно сложно навертели. Разве нельзя сделать как-то так:

Row(
  children: [
    Expanded(
      child: LayoutBuilder(
        builder: (context, constraints) {
          return Row(
            children: [
              ConstrainedBox(
                constraints: BoxConstraints(maxWidth: constraints.maxWidth),
                child: _text(),
              ),
              Flexible(child: _dots()),
            ],
          );
        },
      ),
    ),
    _checkbox(),
  ],
);

Не проверял, но по идее должно работать.

Вызывать WidgetsBinding.instance.addPostFrameCallback из build метода это костыль. По-хорошему build метод должен быть чистой функцией. Отрисовывать dash линию стоило через CustomPaint, либо воспользоваться готовым пакетом. Так же могут быть проблемы с отрисовкой текста. Такие, как потенциальный рассинхрон параметров стилей. А так же двойной пересчет размеров текста, что как-бы не быстрая операция.

Если же вдруг действительно нужно сделать быстрое, чистое и правильное продакшен решение, то, скорее всего, лучшим вариантом будет реализация своего layout-а. В таком случае будет минимум виджетов и разного рода костылей.

Иде тормозят постоянно, даже при банальном наборе текста. Что дико раздражает. Облачные Иде к этим задержкам ещё добавят время на передачу данных на сервер и обратно. И получим этакое программирование по переписке?)

Безусловно скорее всего есть какие-то подводные камни и сложности, учитывая большую кодовую базу языка, возраст и количество уже реализованных фич. Но производительность? Честно говоря, не совсем понимаю, что вы имеете в виду и как она мешает реализовать DU. DU в ООП языках это базовый класс и наследники. И какое-то ключевое слово или атрибут позволяющий указать, что это DU. Плюс exhaustiveness в свитч. И как бы все. Причем здесь производительность не понимаю. Классы и наследование уже давным-давно реализовано. Добавить ключевое слово или атрибут, так же не супер сложная задача. Ну и проверка на полноту тоже не рокет саенс.

только какой-нибудь скриптовый ЯП

Спорно. В том же Dart-е реализовали. И возможно, когда-нибудь и в C# реализуют.

приблуда синтаксиса поверх хеш-массива

А причем здесь хеш-массивы?

Вообще список изменений выглядит так себе. Да есть приятные мелочи (которые давно должны были быть сделаны), но где DU? Похоже не дождемся?

Спасибо, то что нужно.

Было бы здорово, если бы вы подключили более удобную платежку (например с СБП). Попытался оплатить, но требуется номер карты, а возиться с виртуальными особо желания и времени нет.

Не представляю как можно работать за 42-х дюймовым монитором. У меня проблема с переходом на 25-ти или 27-ми дюймовый, а тут целый кинотеатр за рабочим столом... Не думается мне, что это полезно для глаз

Интересно это последний гвоздь? Или еще побарахтается?

В аналогичных ситуациях я стараюсь смотреть на них в положительном ключе (понятное дело, что это сложно - эмоции, все такое; и далеко не всегда получается, но все же...). В том смысле, что если вас не взяли, возможно это наоборот хорошо. Как говорится судьба отвела. С большой долей вероятности работать там было бы не комфортно. А может быть даже пришлось бы уволиться. В таком случае, то что не взяли это даже плюс. Буквально в начале года прошел 10 кругов ада на тех. собесах в Яндекс. По итогу техническое прошел, а вот с командой нет. Конечно расстроился, все это далось очень не легко (ощущение сложилось такое, что такие собесы тупо чтобы тебя вымотать). Но после из Яндекса стали приглашать на собесы с другими командами. И вот ситуация в том, что я теперь думаю, что смысла идти в Яндекс нет. Я как бы и до этого, читал/слышал, что это явно не лучшее место; а теперь даже сам знаю почему. И возможно это даже хорошо, что я туда не попал. В такие моменты я вспоминаю историю из твиттера, где какого-то чувака тоже гоняли хорошенько на собесе, и вроде на все ответил, и вроде как не все так хорошо. В итоге его не взяли, и впоследствии жизнь этого чувака сложилась гораздо лучше, вроде сделал стартап, который реально выстрелил (нюансов истории уже не помню). В любом случае, не расстраивайтесь, и после отдыха продолжаете свои попытки. Рано или поздно и вы найдете свою компанию.

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Mobile Application Developer
Senior
Flutter
Flutter Bloc
MobX
Mobile
Development of mobile applications