Как стать автором
Обновить

Комментарии 18

Люблю Go, но. Вот код на Go:


 backwardIterator := iter.Seq[int](func(yield func(int) bool) {
    for i := range 5 {
        v := arr[i]
        if !yield(i, v) {
            return
        }
    }
})

А вот на Питоне:

 def iter():
    for i in range(5):
        yield i

Что-то мне подсказывает, что в плане читаемости Го очень сильно сдаёт позиции. И это если не вспоминать, что он изначально не мог похвастаться наилучшей читаемостью.

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

Это разные языки. У них разный синтаксис.

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

Это всё понятно, к этому вопросов нет. Я негодую скорее оттого, что вместо привычного по другим языкам yield мы получим очень странный yield. И я знаю, почему именно такой yield мы получим, но оттого совсем не легче.

А бесконечные if err не смущают?

Смущают. Но не более чем бесконечные try ... catch.

А зачем `v := arr[i]` ? В 1.22 же как раз поправили неочевидное поведение переменных в range

Там переменная v в принципе не нужна, потому что это итератор, возвращающий только 1 значение (по крайней мере я так понял замечание). И, соответственно, yield(i).

Да, пример Го я написал с ошибкой.

backwardIterator := iter.Seq[int](func(yield func(int) bool) {
    for i := range 5 
        if !yield(i) {
            return
        }
    }
})

Во так, пожалуй, правильно.

Дженерики сильно упросили и сократили код. А вот итераторы ... Даже не знаю, без них вроде всегда можно обойтись.

Обойтись можно, но вот например, хочу итерироваться по xml/json/т.д. файлу и выдавать объекты поочередно,э. Например, когда не знаешь размер файла, и не хочется его полностью загружать в память

Для этих целей писать свой аналог Rows Аля sql.Rows или функцию, принимающую колбек выглядит как костыли

На мой взгляд Rows даже получше выглядит, задачу тоже решает вполне неплохо.

time.Now().Add() тоже выглядит как костыль на первый взгляд, но если вспомнить C++ с перегрузкой операторов - сразу понятно, что лучше уж так.

Что-то навороты какие-то, аж С++ повеяло:) При этом лично я никаких особых потребностей в итераторах и проблем с классическими циклами не испытываю. Ну подумаешь классический цикл с параметром. Зато просто и прозрачно.

Хотя последнее время погрузился в Go, и некоторых вещей действительно не хватает. Самое простое - это как ни странно тернарный оператор c ? x1 : x2 Приходится писать три отдельных строчки кода с объявлением переменной вместо того, чтобы написать нужный код прямо внутри другого выражения.

Еще немного напрягает, что в "методах классов" нет неявного доступа к полям класса

func (app *Applictaion) foo() {
  app.x = 100; // ok
  x = 100; // error
}

Тернарник ещё ладно, можно терпеть отсутствие, тем более что с ним можно натворить много эпичных багов. Но вот какой-нибудь сахар для проверки указателя или интерфейса на nil (условное присваивание, условный вызов) был бы прям очень кстати.

Тогда надо делать полноценную нуллабельность (спецификатор типа "?" и соответствующие операторы). Но кажется уже поздно, в Go указатели нуллабельны, а другие типы - нет, и если делать то получится слегка кривовато как в C#.

Ошибки, как передавать ошибки из такого енумератора (исключений же у нас нет)?

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

range не предусматривает наличие ошибки. В текущем виде итератор скорее всего придётся оборачивать какой-нибудь структурой, чтобы проверить на ошибку в итераторе. Но выглядит как не самый удобный костыль, надеюсь с ошибкой ещё что-то надумают.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории