Не серчайте, но кажется было бы хорошо если бы из первой пары абзацев можно было понять что собой представляет приложение "Заметки" и что за редактор из него рождали.
Статья взяв "с места в карьер" как бы подразумевает что читатель должен быть в курсе что такое KvadraOS, почему нужно делать приложение с нуля а нельзя взять какое-то готовое (написано же - Android-разработчик - и что, под андроид не нашли ничего? - подумает читатель) - а тут где-то ближе к середине становится ясно что вроде редактор заметок должен быть со стилями (зачем? я не знаю).
Иными словами автор немножко на своей волне, он знает свою задачу, знает проделанную работу и настолько спешит поделиться что предполагает что как минимум половина из этого уже известна и читателю. Вполне возможно такие читатели есть, но я бы не стал делать ставку на то что их много :)
Откуда информация про "под капотом передается указатель"?
в статье ссылка на исходник реализации функции отправки - посмотрите пожалуйста внимательно. она указатель принимает.
ниже в комментариях есть и дизассемблированный код.
мы выполняем функцию, которая замкнула переменную i и изменяет ее внутри тела
в ваших размышлениях отсутствует какое-либо логическое объяснение того почему переменная либо "замыкается" либо нет в зависимости от того прибавляется к ней ноль или нет.
замкнула переменную i и изменяет ее внутри тела
какая функция "замкнула" переменную и "изменяет" её? вы о чём? внешняя её изменяет но не замыкает (т.к. переменная глобальная) а внутренняя замыкает но не изменяет
Не серчайте, но озадачивает идея статьи. Rust - язык с довольно уникальным способом обращения с памятью. В то же время Go использует максимально широко распространённый способ (с небольшими нюансами). Если цель была показать чем интересен и хорош Rust, это лучше было писать "Rust vs All" (подразумевая все прочие языки с автоматическим управлением памятью или как это лучше сказать). А так если придёт почитать человек с бэкграундом в Java или C++ то по этой статье он вынужден будет 60% времени погружаться в детали организации памяти в Go и пытаться понять нужны ему эти детали или нет.
А так написано в достаточно технически подробно, конечно.
нет, как раз копия значения не уходит. канал оперирует ссылками, именно поэтому в примере без прибавления нуля в канал уходит значение взятое по указателю (фактически переданному в канале) - то есть значение на момент вычитывания а не на момент отправки
в том что отправляемое выражение вычисляется в разные моменты в зависимости от того что в этом выражении написано - либо до инструкции <- либо уже при вычитывании (и тут даже буфер не при чем)
Вы абсолютно правы, по крайней мере с "формальной" кочки зрения :)
Но с точки зрения практической получается такая шляпа: Go сейчас занял нишу языка на который "несложно быстро мигрировать" например с Java или C++ (и получить от этого некоторые преимущества). Это влечёт за собой стремление сделать язык достаточно предсказуемым для новичков и "защищённым от дураков". Во многих отношениях эта "политика" действительно прослеживается. Например Go Memory Model настойчиво просит чтобы записи чисел и указателей влезающих в машинное слово были атомарны, и дата рейс на них никогда не приводил бы к проблемам (если бы не это, количество багов в существующем go-шном коде было бы на порядки больше).
С этой точки зрения проектировать язык так чтобы он работал ожидаемо только в расчете на очень грамотного и внимательного программиста - явное отступление от этой стратегии. Тем более здесь фикс возможен тривиальный (как коллеги упомянули выше).
не совсем так, "статически" и "динамически" я соотношу строго с двумя вышеупомянутыми трактовками "data race". наверное не очень внятно это выразил. если мы трактуем "data race" как "потенциальную возможность" а не как факт, то race detector уместно было бы сделать синтаксическим анализатором (он однако вместо этого воплощён только как "динамическая" проверка - что соответствует первой трактовке).
поведение в статье противоречит описанию операции отправки:
спасибо за ссылку на спецификацию - действительно как будто нарушается, если только не считается что communication begins - это только после разблокировки
Но на чем основана ваша точка зрения, что между операциями над i есть отношение "happens before/after", о котором вы пишете?
тут опять всё упирается в то хотим ли мы чтобы это отношение было доказуемо "статически" (из наличия мьютексов например) или динамически (тогда любой способ который позволит физически разнести операции во времени - годится). Go Memory Model по-моему нигде точно не говорит какие способы (механизмы) обеспечения happens before/after мы признаём. В частности synctest.Wait() является ли оным
глобальная переменная не в контексте горутины (или любой другой функции), ей не нужно туда попадать. можете скомпилировать такой код и убедиться отладчиком:
var a = 5
func main() {
var b = 7
go func() {
a += 5
b += 7
}()
//...
}
В gdb если дизассемблировать горутину, получаются вот такие 3 строчки:
первая грузит в RAX адрес контекста горутины со смещением 8 - очевидно адрес переменной B как он в контексте горутины виден (RDX хранит указатель на этот контекст)
вторая добавляет число 5 в переменную A адресуемую непосредственно относительно счетчика команд, то бишь по абсолютному адресу в коде
третья добавляет число 7 в переменную B (адрес её в RAX)
Так что B замыкается, а A не замыкается. Глобальные переменные всем функциям видны без ограничений и живут все время жизни программы - замыкать их не требуется...
Конкуретность означает любое выполнение в разных горутинах.
вы можете предложить ссылку на это определение в какой либо документации по Go?
тут есть такая проблема что упомянутая выше цитата из Go Memory Model оставляет возможность для двоякой трактовки, сводящейся к тому что:
data race это именно ситуация когда две операции доступа к переменной происходят с пересечением по времени
data race это потенциальная возможность возникновения такой ситуации исходя из организации кода
Я (как и race detector в go) использую первую трактовку. Спорить тут вроде бессмысленно - если определение нечёткое, можно до опупения защищать каждый свою точку зрения :)
да не, это вы про "недозамкнутость" замыканий - это даже не проблема, это просто "ну такая реализация" - действительно известная спокон веку. языки примерно поровну поделились на те которые замыкают полностью и неполностью (в основном ради соображений эффективности)
но здесь речь именно о реализации отправки в канал.
чтобы не конфузить читателей, заменил на глобальную переменную, тогда про замыкание уже речь не идёт - а проблема остаётся :) спасибо
да вроде буквально только год-полтора назад как мне "многоцифровой" на "простоцифровой" пришлось изменить... даже меньше, я гляжу сейчас по интернетам что эта волна возмущения много где прокатилась, например
не-не, там не пин связанный с данными, сохранёнными в браузере текущем, как у других, а реально 4 цифры вместо пароля. вот сейчас в инкогнито логинюсь из браузера который никогда не использую для этих целей, через прокси в чужой стране, с ноута которым тоже не пользуюсь для заходов в банки - спрашивает сначала 6-значный код из СМС, потом 4-значный который когда-то установлен вместо пароля (на другом компьютере, браузере и т.п.)
писал в поддержку, ну сказали мол не писай, всё будет зашибись, у нас спецы круче чем везде (видимо поэтому все остальные лохопеты до такого еще не додумались :)
Не серчайте, но кажется было бы хорошо если бы из первой пары абзацев можно было понять что собой представляет приложение "Заметки" и что за редактор из него рождали.
Статья взяв "с места в карьер" как бы подразумевает что читатель должен быть в курсе что такое KvadraOS, почему нужно делать приложение с нуля а нельзя взять какое-то готовое (написано же - Android-разработчик - и что, под андроид не нашли ничего? - подумает читатель) - а тут где-то ближе к середине становится ясно что вроде редактор заметок должен быть со стилями (зачем? я не знаю).
Иными словами автор немножко на своей волне, он знает свою задачу, знает проделанную работу и настолько спешит поделиться что предполагает что как минимум половина из этого уже известна и читателю. Вполне возможно такие читатели есть, но я бы не стал делать ставку на то что их много :)
в статье ссылка на исходник реализации функции отправки - посмотрите пожалуйста внимательно. она указатель принимает.
ниже в комментариях есть и дизассемблированный код.
в ваших размышлениях отсутствует какое-либо логическое объяснение того почему переменная либо "замыкается" либо нет в зависимости от того прибавляется к ней ноль или нет.
какая функция "замкнула" переменную и "изменяет" её? вы о чём? внешняя её изменяет но не замыкает (т.к. переменная глобальная) а внутренняя замыкает но не изменяет
вы то ли не прочли статью, то ли прочли как-то не так. непонятно что случилось, простите :)
Не серчайте, но озадачивает идея статьи. Rust - язык с довольно уникальным способом обращения с памятью. В то же время Go использует максимально широко распространённый способ (с небольшими нюансами). Если цель была показать чем интересен и хорош Rust, это лучше было писать "Rust vs All" (подразумевая все прочие языки с автоматическим управлением памятью или как это лучше сказать). А так если придёт почитать человек с бэкграундом в Java или C++ то по этой статье он вынужден будет 60% времени погружаться в детали организации памяти в Go и пытаться понять нужны ему эти детали или нет.
А так написано в достаточно технически подробно, конечно.
нет, как раз копия значения не уходит. канал оперирует ссылками, именно поэтому в примере без прибавления нуля в канал уходит значение взятое по указателю (фактически переданному в канале) - то есть значение на момент вычитывания а не на момент отправки
в том что отправляемое выражение вычисляется в разные моменты в зависимости от того что в этом выражении написано - либо до инструкции
<-либо уже при вычитывании (и тут даже буфер не при чем)Вы абсолютно правы, по крайней мере с "формальной" кочки зрения :)
Но с точки зрения практической получается такая шляпа: Go сейчас занял нишу языка на который "несложно быстро мигрировать" например с Java или C++ (и получить от этого некоторые преимущества). Это влечёт за собой стремление сделать язык достаточно предсказуемым для новичков и "защищённым от дураков". Во многих отношениях эта "политика" действительно прослеживается. Например Go Memory Model настойчиво просит чтобы записи чисел и указателей влезающих в машинное слово были атомарны, и дата рейс на них никогда не приводил бы к проблемам (если бы не это, количество багов в существующем go-шном коде было бы на порядки больше).
С этой точки зрения проектировать язык так чтобы он работал ожидаемо только в расчете на очень грамотного и внимательного программиста - явное отступление от этой стратегии. Тем более здесь фикс возможен тривиальный (как коллеги упомянули выше).
не совсем так, "статически" и "динамически" я соотношу строго с двумя вышеупомянутыми трактовками "data race". наверное не очень внятно это выразил. если мы трактуем "data race" как "потенциальную возможность" а не как факт, то race detector уместно было бы сделать синтаксическим анализатором (он однако вместо этого воплощён только как "динамическая" проверка - что соответствует первой трактовке).
спасибо за ссылку на спецификацию - действительно как будто нарушается, если только не считается что communication begins - это только после разблокировки
попробую из любопытства тикет создать
тут опять всё упирается в то хотим ли мы чтобы это отношение было доказуемо "статически" (из наличия мьютексов например) или динамически (тогда любой способ который позволит физически разнести операции во времени - годится). Go Memory Model по-моему нигде точно не говорит какие способы (механизмы) обеспечения happens before/after мы признаём. В частности
synctest.Wait()является ли онымглобальная переменная не в контексте горутины (или любой другой функции), ей не нужно туда попадать. можете скомпилировать такой код и убедиться отладчиком:
В gdb если дизассемблировать горутину, получаются вот такие 3 строчки:
0x0000000000471620 <+0>: mov 0x8(%rdx),%rax
0x0000000000471624 <+4>: addq $0x5,0x96b44(%rip) # 0x508170
0x000000000047162c <+12>: addq $0x7,(%rax)
первая грузит в RAX адрес контекста горутины со смещением 8 - очевидно адрес переменной B как он в контексте горутины виден (RDX хранит указатель на этот контекст)
вторая добавляет число 5 в переменную A адресуемую непосредственно относительно счетчика команд, то бишь по абсолютному адресу в коде
третья добавляет число 7 в переменную B (адрес её в RAX)
Так что B замыкается, а A не замыкается. Глобальные переменные всем функциям видны без ограничений и живут все время жизни программы - замыкать их не требуется...
вы можете предложить ссылку на это определение в какой либо документации по Go?
тут есть такая проблема что упомянутая выше цитата из Go Memory Model оставляет возможность для двоякой трактовки, сводящейся к тому что:
data race это именно ситуация когда две операции доступа к переменной происходят с пересечением по времени
data race это потенциальная возможность возникновения такой ситуации исходя из организации кода
Я (как и race detector в go) использую первую трактовку. Спорить тут вроде бессмысленно - если определение нечёткое, можно до опупения защищать каждый свою точку зрения :)
да не, это вы про "недозамкнутость" замыканий - это даже не проблема, это просто "ну такая реализация" - действительно известная спокон веку. языки примерно поровну поделились на те которые замыкают полностью и неполностью (в основном ради соображений эффективности)
но здесь речь именно о реализации отправки в канал.
чтобы не конфузить читателей, заменил на глобальную переменную, тогда про замыкание уже речь не идёт - а проблема остаётся :) спасибо
разнаряженные :)
да вроде буквально только год-полтора назад как мне "многоцифровой" на "простоцифровой" пришлось изменить... даже меньше, я гляжу сейчас по интернетам что эта волна возмущения много где прокатилась, например
https://www.banki.ru/services/questions-answers/question/710970/
кодовые цифры на других банках - они к браузеру привязаны. а здесь это типа пароля теперь :)
про бедолаг-разработчиков, это утрировано
есть там менеджеры, аналитики, тестировщики - целая банда трудится, как и везде :)
и не должно быть вот этого как в старом фильме:
-- я больше никогда не смогу ходить!
-- почему? что с тобой сделали?
-- они... они связали мне шнурки на ботинках!
хех, в ВТБ пароль (пока это были не 4 цифры) был не то что регистронезависимый, а вообще только из цифр (хоть и больше четырех)
да, есть, но там другой текст ("подтверждение смены пароля...")
ну и кстати попытки смены пароля тоже не отображаются по-моему :)
я на это смотрю больше с позиции IT-шника - по мне сделать оповещение в 2 случаях и не сделать в 3-м это косяк :)
не-не, там не пин связанный с данными, сохранёнными в браузере текущем, как у других, а реально 4 цифры вместо пароля. вот сейчас в инкогнито логинюсь из браузера который никогда не использую для этих целей, через прокси в чужой стране, с ноута которым тоже не пользуюсь для заходов в банки - спрашивает сначала 6-значный код из СМС, потом 4-значный который когда-то установлен вместо пароля (на другом компьютере, браузере и т.п.)
писал в поддержку, ну сказали мол не писай, всё будет зашибись, у нас спецы круче чем везде (видимо поэтому все остальные лохопеты до такого еще не додумались :)