Rust и Golang хороши, но бывают случаи, когда Rust может упростить задачу. И в Rust есть что-то, чего я никогда не чувствовал в других языках.
Пример 1
Моя программа загружает огромные данные и записывает в локальный файл (или сокет, или БД, или что-то еще), я выделяю 1 МБ памяти в качестве буфера для получения данных, а затем записываю в файл. При использовании Golang сигнатура функции передачи данных в средство записи файлов может выглядеть примерно так: writeToLocal(buffer []byte)
Вопрос: после одного вызова writeToLocal следует ли повторно использовать 1 МБ buffer для получения данных из интернета? Или я должен выделить новый буфер? Не исключено, что код внутриwriteToLocal будет хранить указатель, указывающий на buffer, который я ему передал. Если я изменю свой buffer , я могу перезаписать некоторые данные, которые еще не записаны на диск.
В таких случаях я читаю исходный код или документы writeToLocal, чтобы убедиться, что определенные действия безопасны. Лишь бы перестраховаться.
Что, если я использую Rust? Такая функция либо принимает ссылку на буфер, либо владеет им, поэтому мне вообще не нужно об этом думать.
Пример 2
Когда у меня есть 2 горутины в программе Golang, я могу передавать некоторые данные туда и обратно по каналам. Когда я прохожу string или []byte , я ни о чем не беспокоюсь. Но я начал беспокоиться при передаче таких вещей, как []SomeStruct, где SomeStruct может содержать указатели, указывающие на SomeOtherStruct или слайс или что-то еще.
При использовании Rust мне вообще не нужно об этом думать. Если я передам что-то, что нельзя передать, оно не скомпилируется.
Точно так же при использовании функций/классов на различных языках, таких как Java, C#, Golang, я обнаружил, что постоянно открываю веб-страницы документации и нажимаю CTRL-F для поиска слов «поточно-безопасный». Иногда мне приходится очень внимательно читать документы, чтобы убедиться, что выполнение определенных действий определенным образом безопасно или небезопасно.
При использовании Rust вы тратите на это гораздо меньше времени.
Пример №3
В Golang есть функция DeepEqual для сравнения среза/структуры/и т. д. Когда я впервые использовал его, я подумал: не заканчивается ли сравнение на равенство на втором уровне? Или это может быть глубже, когда у вас есть ломтик ломтика? В конце концов, я внимательно прочитал документацию, чтобы убедиться, что знаю, как это работает. Для большинства других языков есть аналогичные функции, и я всегда трачу время на чтение документации. Не говоря уже о том, что через какое-то время я забыл то, чему научился, а потом обнаружил, что снова и снова читаю одни и те же документы.
В Rust я просто везде использую == и даже не думаю об этом. Если дети могут сделать == , то родители могут сделать == . Обычно в Rust все так просто.