LINUX.ORG.RU
ФорумTalks

А как вообще Go взлетел?

 


1

3

Решил вот посмотреть на язык, читаю, дошел до слайсов.

                                                                                                                                                                                                         
package main

import (
	"fmt"
)

func main() {
	a := []int{1, 2, 3, 4, 5}
	b := []int{1, 2, 3, 4, 5}
	c := a[1:3]
	d := b[1:5]
	c = append(c, 10)
	d = append(d, 10)
	c[0] = 0
	d[0] = 0
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
	fmt.Println(d)
}
Вывод:
[1 0 3 10 5]
[1 2 3 4 5]
[0 3 10]
[0 3 4 5 10]

То есть в зависимости от одного индекса зависит, будет ли меняться низлежащий массив или нет. Да, я знаю про синтаксис [1:3:3], но это избыточность, и по умолчанию так же все равно не пишут. И если мне это в функцию дают, мне что, каждый раз сравнивать size и capacity, чтобы дел не напороть? А учитывая, что я не могу в сигнатуре функции указать константность, это еще сильнее усугубляет.
Ну а про классические претензии вроде отсутствия дженериков и перегрузки, но при этом существования generic-like встроенных типов с ad-hoc синтаксисом, жуткой обработки ошибок и прочего, я уж молчу, это давно уже обсосали везде. Вот и вопрос, как оно взлетело?

★★

Последнее исправление: keyran (всего исправлений: 1)

Вот и вопрос, как оно взлетело?

Google же. Хороший веб делают.

BceM_IIpuBeT ★★☆☆☆
()

Ты забыл упомянуть про преимущества и вытекающей из них нише, в которой Go нет равных

makoven ★★★★★
()
Ответ на: комментарий от makoven

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

keyran ★★
() автор топика
Ответ на: комментарий от Unununij

А как Java взлетела? JS?

Java в свое время была вполне приличным языком, JS взлетел за счет массовости // К.О.

tailgunner ★★★★★
()

Кто вам сказал, что го взлетело? Хайпят че-то хайпят (как руст), но ничего на нем никто не делает все равно. Разве что пара болванов, их всегда есть.

Deleted
()

Да я бы не сказал, что он куда-то там взлетел. Кто-то использует..

Im_not_a_robot ★★★★★
()
Ответ на: комментарий от keyran

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

urxvt ★★★★★
()

лучше бы делом занялся, чем обсосанную тыщу раз тем снова сосать

oxo
()

Я сначала подумал, что это баг (причем в строчке, где добавляется значение к c). Но потом я увидел это, и мне поплохело что-то.

uuwaan ★★
()
Последнее исправление: uuwaan (всего исправлений: 1)
Ответ на: комментарий от keyran

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

makoven ★★★★★
()
Ответ на: комментарий от Deleted

но ничего на нем никто не делает все равно

Вся популярная контейнеризация на нём и уйма полезного сетевого софта от IPFS до Syncthing.

KRoN73 ★★★★★
()
Ответ на: комментарий от urxvt

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

keyran ★★
() автор топика
Последнее исправление: keyran (всего исправлений: 1)

У меня вот этот вот баг вылез в мной написаном и задеплоеном в продакшн коде, который я мимо тестинга туда вковбоил. В праздники. Когда я был один в офисе. Словил сегфолт в Go из-за этого в многопоточном коде. Как же я искал ошибку долго, потому что было далеко не все так очевидно как у тебя в примере.

P.S. Я обычно вышеописаное не делаю, но там не было риска реального ущерба и легкий роллбек.

vertexua ★★★★★
()
Последнее исправление: vertexua (всего исправлений: 3)
Ответ на: комментарий от Deleted

Только docker

Можно подумать, сегодня есть _популярные_ альтернативы :D LXC/LXD и рядом не валялся. Что ещё?

KRoN73 ★★★★★
()
Ответ на: комментарий от Deleted

по мне так LXC намного удобнее

У него свой набор задач. Я активно использую и LXC, и Docker на одних и тех же машинах, в зависимости от задач.

Но я писал не о том, что удобнее или лучше, а о том, что популярнее :) LXC и близко не лежит по популярность с Docker. Разница в Google Trends на уровне порядка с лишним.

KRoN73 ★★★★★
()
Ответ на: комментарий от deadNightTiger

Хватит уже сравнивать виртуализацию всей ОС с контейнеризацией одного процесса.

Но, справедливости ради, оба этих инструмента, хотя и предназначены для разных целей, являются средствами контейнеризации :)

Но в любом случае, когда сегодня говорят «контейнеризация», то в over 90% случаев имеют в виду Docker. Так что ниша у Golang есть уже железная и пока неколебимая.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

У docker есть общественный репозиторий с образами всякого софта, видимо для хипстеров это решающую роль сыграло.

Deleted
()

man «указатели»

package main

import (
	"fmt"
)

func main() {
	a := []int{1, 2, 3, 4, 5}
	b := []int{1, 2, 3, 4, 5}

	c := make([]int, len(a[1:3]))
	d := make([]int, len(b[1:5]))
	
	copy(c, a[1:3])
	copy(d, b[1:5])

	c = append(c, 10)
	d = append(d, 10)

	c[0] = 0
	d[0] = 0

	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
	fmt.Println(d)
}
Siado ★★★★★
()
Последнее исправление: Siado (всего исправлений: 1)
Ответ на: комментарий от vertexua

P.S. Я обычно вышеописаное не делаю, но там не было риска реального ущерба и легкий роллбек.

Вертехуа нахуавертил

Siado ★★★★★
()
Ответ на: комментарий от Siado

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

keyran ★★
() автор топика
Ответ на: комментарий от keyran

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

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

Siado ★★★★★
()
Ответ на: комментарий от Siado

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

keyran ★★
() автор топика
Последнее исправление: keyran (всего исправлений: 1)
Ответ на: комментарий от Siado

Да вообще умиляет это «новые ЯП, технологии, 2кN год итп». Никак не понять, что ЯП под имеющиеся архитектуры уже ЕСТЬ и пишут любой софт на них уже дохера лет. Особенно умиляет когда называют софт технологиями.

Вот сделаете новую архитектуру и под нее потокобезопасный без UB без утечек ЯП, когда и будете это все технологиями называть, а пока вы сраная унылая хипстота!

Deleted
()
Ответ на: комментарий от Deleted

Никак не понять, что ЯП под имеющиеся архитектуры уже ЕСТЬ и пишут любой софт на них уже дохера лет

Да, непонятно, нахрена нужен этот хипстерский C, когда есть FORTRAN.

KRoN73 ★★★★★
()
Ответ на: комментарий от beastie

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

keyran ★★
() автор топика
Ответ на: комментарий от KRoN73

Да ладно. С в свое время решал некоторые проблемы. Это новомодное go решает только отсутствие толи мозга толи желания нормально обучаться, а может это одно и тоже.

Deleted
()

Куда взлетело? Когда? 3,5 хипстора на нём пишут, мода знаете ли. Через перу лет закопают.

IPR ★★★★★
()

Занял свою нишу, но довольно маргинальную. Пока далеко до взлета.

Valeg ★★★
()
Ответ на: комментарий от Deleted

Ага, как и Xen, как и KVM. Кругом макаки, и макаки двигают прогресс.

menangen ★★★★★
()
Ответ на: комментарий от keyran

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

Так append() и есть куча кода с realloc внутри. Просто нужно проникнуться слайсами и подходом Го, а не применять парадигмы с других языков. По мне так все логично. И то что append() возвращает (или может) ссылку на новый участок памяти говорит твой же код (заметь, это видно без всякой доки по append()). А именно то что ты используешь дальше результат возвращенный самим же append().

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

Если бы речь шла только о слайсах с и d — без возражений. То, что лежит в них, вполне укладывается в любую логику. Я же говорю о том, что происходит со слайсами a и b. Из-за того, что d — слайс до конца b, он реаллоцируется и b не изменяется, а вот в случае с слайсом c абсолютно те же операции приводят к изменению a. Вот в этом-то и недовольство, что разница между c и d минимальна, а сайд-эффекты разнятся значительно.

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

keyran ★★
() автор топика
Последнее исправление: keyran (всего исправлений: 1)
Ответ на: комментарий от keyran

Ага, теперь я понял о чем ты. Ну... ХЗ, мне все же кажется из самого понятия slice это следует. Хотя да, очень error-prone штука получается, с которой легко застрелится по-ошибке даже самому Пайку. :)

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

Как по мне, slice должен быть «окном» в низлежащий массив. Все, что за пределами окна, ему доступно быть никак не должно. Давать или нет доступ на изменение того, что в окне - это уже другой вопрос, и он такого недоразумения вызывать не должен.

keyran ★★
() автор топика
Последнее исправление: keyran (всего исправлений: 1)
Ответ на: комментарий от Bad_ptr

А как Java взлетела?

Томми прорекламировал

Siado ★★★★★
()
Ответ на: комментарий от urxvt

Я покрутил программу, и мне нелогичным кажется такой факт: сразу после создания у слайса d len=4, cap=4, но у слайса c len=2, cap=4. Например, пишу я функцию, которая возводит элементы слайса в квадрат, и передаю ей нижнюю половину массива. Получаю возможность внутри функции легально выйти за границы дозволенной области. Я так понимаю, что помимо синтаксиса [low:high] есть вариант [low:high:cap], и недоумеваю, почему по умолчанию cap ставится до конца нижележащего массива. Если бы ёмкость ставилась по умолчанию равной длине слайса, обсуждаемой подставы бы не случалось.

uuwaan ★★
()
Последнее исправление: uuwaan (всего исправлений: 1)
Ответ на: комментарий от baka-kun

Ты вот сейчас написал, как будто Golang – это какая-нибудь религия. Это не религия, это инструмент. Это всё равно что представить автомобиль, где педали жмутся руками, а руль крутится ногами, и на вопрос: «Нафига?» – сказать: по определению.

uuwaan ★★
()
Последнее исправление: uuwaan (всего исправлений: 1)
Ответ на: комментарий от uuwaan

Ты вот сейчас написал, как будто Golang – это какая-нибудь религия.

Я так описал, как будто именно так определены слайсы в Golang: The capacity is the number of elements in the underlying array (beginning at the element referred to by the slice pointer).

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

Ну, значит Golang — такой автомобиль.

baka-kun ★★★★★
()

Просто я помню тред на английском языке (на Stackoverflow, кажется), где ОП искренне удивлялся, как это так append может распределить новый массив: он писал всегда append(a, x) без переприсваивания, и у него большую часть времени работало нормально такое.

Проводя аналогию с Сишным realloc: никто же не надеется, что этот вызов никогда не переместит блок памяти, все же и на NULL проверяют и новый адрес запоминают.

Вот документ, который описывает синтаксис задания ёмкости слайса, там замечательная фраза:

It would occasionally be useful, for example in custom []byte allocation managers, to be able to hand a slice to a caller and know that the caller cannot edit values beyond a given subrange of the true array.

The addition of append to the language made this somewhat more important, because append lets programmers overwrite entries between len and cap without realizing it or even mentioning cap.

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

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

uuwaan ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.