Pull to refresh
-16
0
Send message
Разобрался. Оказывается, на Go async/await вполне можно сделать в более-менее общем виде:
func WhenAll(f interface{}, s interface{} ) Futurer {
    v := reflect.ValueOf(s)
    fn := reflect.ValueOf(f)
    if reflect.TypeOf(s).Kind() != reflect.Slice {
        panic("not slice")
    }
    if reflect.TypeOf(f).Kind() != reflect.Func {
        panic("not func")
    }
    if reflect.TypeOf(f).In(0) != v.Type().Elem() {
        panic("wrong arg type")
    }
    l := v.Len()
    var result = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(f).Out(0)), l, l) 
    var wg sync.WaitGroup
    wg.Add(l)
    for i := 0; i < l; i++ {
        i := i
        go func() {
            in := []reflect.Value{v.Index(i)}
            result.Index(i).Set(fn.Call(in)[0]) 
            wg.Done()
        }()
    }
    return future{
        await: func() interface{} {
            wg.Wait()
            return result.Interface()
        },
    }
}
Как я понял из текста, он не наступал, это люди сказали, что может наступить. Да и странно это как-то, в шарпе можно так делать, а в го нельзя. Хотя, там ведь тоже TPL неспроста придумали.
Кстати, был бы благодарен, если знатоки рефлексии в го показали, как это переписать, чтоб WhenAll принимала func(interface{}) interface{}
Да, го достаточно бедный, сущностей немного, иногда приходится извращаться, но потом этот ужас обычно прячется в библиотеки. В результате возможность переиспользования кода вполне на уровне, зря народ говорит про write-only. Хотя, с генериками такой, например, код был бы повеселее
type Futurer interface {
    Await() interface{}
}
type future struct {
    await func() interface{}
}
func (f future) Await() interface{} {
    return f.await()
}
func WhenAll(f func(intTree) commentTree, v []intTree ) Futurer {
    l := len(v)
    var result = make([]commentTree, l)
    var wg sync.WaitGroup
    wg.Add(l)
    for i := 0; i < l; i++ {
        i := i
        go func() {
            result[i] = f(v[i])
            wg.Done()
        }()
    }
    return future{
        await: func() interface{} {
            wg.Wait()
            return result
        },
    }
}
func GetCommentsTree(tree intTree) commentTree {
    children := WhenAll(GetCommentsTree, tree.children)
    var value = getCommentById(tree.id)
    var childrenResults = children.Await().([]commentTree)
    return commentTree{ value, childrenResults }
}
Разве? Ведь loadComments вызывается только один раз.
Кстати, рекурсивную функцию, пожалуй, тоже удобнее засунуть вовнутрь.
func loadComments(root intTree) map[int]comment {
    var wg sync.WaitGroup
    result := make(map[int]comment)
    in := make(chan int)
    out := make(chan comment)
    nWorkers := 2
    for i := 0; i < nWorkers; i++ {
        go func() {
            for id := range in {
    	        out <- getCommentById(id)
            }
        }()
    }
    var loadCommentsInner func(node intTree)
    loadCommentsInner = func(node intTree) {
	for _, c := range node.children {
            loadCommentsInner(c)
        }
        wg.Add(1)
        in <- node.id
    }
    go func() {
        for c := range out {
            result[c.Id] = c
    	    wg.Done()
        }
    }()
    loadCommentsInner(root)
    close(in)
    wg.Wait()
    close(out)
    return result
}
Я не утверждаю, что это правильно. Просто я так привык писать на го. как-то так вышло
Да, на любом. Особенно удобно, если язык поддерживает семантику перемещения и её не требуется обеспечивать вручную.
В го каналы применяют для решения двух проблем многопоточности — явной передачи права на владение объектом и управления временем жизни потока. Ну, в теории. А так, обычное дело: берешь библиотеку, а там утечка потоков.
Do not communicate by sharing memory; instead, share memory by communicating.
Я бы, наверное, описанную задачу решал так: не запускал горутину на каждую запись, а создал пул воркеров с входными и выходными каналами, во входной пихал айдишники, с выходного сваливал результаты в мап, потом закрыл входной чтоб воркеры закончились, а из мапа по-новой построил дерево. Никаких блокировок или гонок.
Как эта библиотека работает? Там можно настраивать количество воркеров?
Если записей миллион, сколько сетевых соединений будет создано?
DJI получил систему самонаведения на самолеты и вертолеты?
Я о том же. Большое количество ссылок на статью отнюдь не гарантирует её качества. Однако, и самоцитирование в общем случае не коррелирует с низким качеством работ автора.
Ссылка — это не отзыв. Это дополнительная информация по теме статьи.
Или, например, если в первой статье у вас постановка задачи исследования и предложение новых подходов, а во второй — полученные результаты, то достаточно странно было бы не сослаться из второй на первую.
Хипстеры используют E-ink. OLED для нищебродов, он сейчас дешевле экрана от Нокии. Какой смысл в экономии флэша, если чипы с 4к и 128к стоят ровно те же 100 рублей? Да, код будет близким, если библиотеки похожие. Только и размер примерно совпадёт. Добавить WiFi и сервер с TLS и привет, мегабайт.
Новые языки не так плохи, удобство разработки быстро перевешивает накладные расходы на рантайм, особенно в разовых проектах.
Эмбед разный. Инструмент по задаче.
Не всем надо гнать десятки мегабайт данных в секунду. Если мне нужно раз в минуту взять число из датчика CO2, выложить его на OLED экран и отдать по вайфаю, скриптовый язык подойдет оптимально. С использованием готовых модулей такой проект редко превышает десяток строк кода. Правда, в 128 килобайт флэша это всё лезет с трудом, модули приходится минифицировать. Но и с плюсами порой удивляешься, как резко растёт бинарник после всего одного дополнительного библиотечного вызова.
Самое простое программирование микроконтроллеров, которое мне доводилось видеть — проект Espruino с почти полноценным Javascript на борту. Интерпретатор даёт непривычный опыт, особенно в отладке.
Заливал на Maple mini, плата вроде Bluepill, но вдвое дороже, чип там CB вместо C8.
Для экономии сейчас можно смотреть на esp8266.
Объясните, как фразу:
Управление выгодами планируется и управляется всесторонне.
вообще можно использовать в какой-либо деятельности.
Абсолютное количество большой роли не играет. Если трава растет сама, без вспашки, посева, полива и уборки, затраты могут быть кратно ниже, чем в овощеводстве, например.
Почему не годятся? Человек чем-то от других животных принципиально отличается? Китайцы, пользуют, в результатае выращивают рис по 3000 лет на одном поле без севооборота.
если упорядочить по self%, Шевкунов будет на 8-м месте, а не на 800-м
Так номер строки — это же просто id
Точно нет, потому что и id и числа в колонке self% упорядочены.
PS. Глянул файлик за 17 год. Из 100000 имеют индекс самоцитирования выше 50% меньше 300 человек. Из них русских 13, потенциальных (не указана страна) ещё 6. 9 австралийцев, 12 китайцев, 15 немцев, 18 англичан, 14 итальянцев, 18 японцев, 1 украинец и 44 американца. Расходимся?
А ещё, если в статье нет ссылок на публикации в этом же журнале, отказывают, как не соответствующей тематике.

Information

Rating
Does not participate
Registered
Activity