2015-08-24 2 views
3

я был заинтересован в ржавчине, и поэтому я начал читать руководство по программированию ржавчины на сайте ржавчины, и обнаружил, что переменные объявлены следующим образом:Почему Ржавчина беспокоит «пусть»?

let x: i32 = 5; 

Что означает присвоить целое значение 5 переменных тип integer 32 бит, на который будет обозначаться обозначение x с этого момента и далее.

Главный вопрос: почему ключевое слово let существует? Это кажется излишним, как будто он фактически ничего не делает.

Я предполагаю, что компилятор сможет сказать, что следующая переменная (или константной переменной) Объявление:

x: i32 = 5; 

Там не появляется, чтобы быть причиной для let ключевого слова, но предположительно там - - разумная причина, потому что Rust сосредоточен на безопасности. Так в чем же причина?


Редактировать: Дополнение: В качестве аргументов функции ключевое слово let не требуется. Вот пример:

fn add1(x: i32) -> i32 
{ 
    x = x + 1 
} 

Это кажется немного странным - это «выглядит как» проход по ссылке из-за недостающего let. Но это не так. Это пропуск по значению. (Или, по крайней мере, я думаю, что это так.) Является ли это синтаксической непоследовательностью?


Как и в сторону, я бы найти его гораздо более логичным, чтобы изменить это заявление вокруг и написать:

i32 x = 5; 

Поместите двоеточие там, если вы:

i32: x = 5; 

Я думаю, что я бы счел это более логичным, потому что:

  • При программировании вы обычно знаете, какой тип данных вы хотите, прежде чем думать о имени для него.

Возможно, некоторые думают наоборот? Но это подводит меня к другому моменту; как можно объявить несколько переменных одного типа в Rust? Такие как:

let x, y, z: i32 = {4, 5, 5} // A guess of what this might look like? 

Или это просто не разрешено в Rust?

+0

Я не понимаю вашу точку зрения. В сигнатуре функции контекст сообщает нам, что мы объявляем параметры и не присваиваем ничего. И как создается впечатление, что что-либо происходит по ссылке, без каких-либо «и» или других индикаторов, выходит за меня. – delnan

+0

@delnan Прочтите внимательно - я сказал, что это не по ссылке, но похоже, что это возможно. – user3728501

+0

Я понимаю это. Я просто не понимаю, как это может выглядеть. Нет ничего, что указывало бы на это. Как вы заметили, единственное различие заключается в отсутствии 'let', что это связано с by-value/by-reference? – delnan

ответ

25

Rust имеет локальный тип вывода, поэтому тип обычно не нужно писать; let x = 5; хватит. x = 5; будет совсем другим, так как это не будет объявить переменной x, а Rust очень намеренно разделяет объявление и назначение.

Это также на самом деле let PATTERN = EXPR;, а не только let IDENT = EXPR;, поэтому удаление ключевого слова let вызовет грамматическую двусмысленность.Образец может быть mut x (изменение переменной привязки изменчиво), это может быть (a, b), означающее распаковку кортежа, & c.

Вы считаете, что только i32 x = 5; имеет смысл, потому что вы привыкли к языкам, таким как C++. Серьезно, кто придумал эту идею? Для чисто философских оснований имеет смысл иметь тип после имени, чем раньше, и иметь просто тип объявления переменных тоже глупо. Там всякого рода грамматическая двусмысленность. Вывод типа, позволяющий полностью опустить тип, намного лучше подходит во всем.

+0

Интересные моменты, поднятые здесь - можете ли вы привести пример такой двусмысленности? И чтобы ответить на параграф 3: Нет, много лет назад, когда я прекратил использовать Basic и начал программировать на C, мне понравилось, что ключевое слово «dim» исчезло, потому что я не видел никаких причин для его присутствия. Я не понимаю вашу точку зрения по философским соображениям - я думаю, что это, возможно, личное предпочтение, предпочитаете ли вы сначала тип или идентификатор? Каков ваш философский аргумент в пользу того, чтобы иметь тип после? – user3728501

+0

Итак, с точки зрения зрения присвоение значения типу менее глупо, чем i32 x = 5; ? – seb

+0

_ «Кто придумал эту идею?» _ [Деннис Ричи сделал] (https://www.bell-labs.com/usr/dmr/www/chist.html). _ «Аналогичные рассуждения привели к синтаксису объявления для имен, отражающих синтаксис выражения, в котором обычно появляются имена». _ В ретроспективе это был неудачный ход (поскольку он удалил всю надежду на нечувствительность к контексту с языка), но это вероятно, казалось отличной идеей в то время точно по философским соображениям («как вы обобщаете синтаксис типа композиции?») – Wtrmute

5

Это значительно упрощает грамматику. Помните, что на левой стороне есть полный рисунок, это не на самом деле let var это let pattern.

Как можно объявить несколько переменных одного типа в Rust?

Это совершенно другой вопрос, но нет прямого способа сделать это, нет, по крайней мере, не так, как вы думаете. Вы можете

let (a, b, c) = (1, 2, 3); 

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

8

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

Во-вторых, введите вывод. Независимо от того, где написан тип, его можно опустить, поэтому вам нужно указать let или другой маркер, чтобы отличать назначение от декларации. (Вы можете использовать технически let x = ...; и Type x = ...;, но почему? Это не тип, это отсутствие типа.)

В-третьих, общностью. let работает с любым (неопровержимым) шаблоном, включая те, которые удваиваются как совершенно законные выражения: StructLiteral { field: x, other_field: y } и Some(thing). Это источник еще большей двусмысленности, если не для синтаксического анализатора (сейчас он отклоняет Some(a) = b), а затем для людей.

В-четвертых, в то время как вы могут быть использованы для type name, существует давняя традиция name: type, и она набирает обороты господствующего без Руста делать (например, в Scala).

В-пятые, я оспариваю это:

При программировании вы обычно знаете, что «типа» данные, которые вы хотите, прежде чем придумать название для него.

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

+0

Я не совсем понимаю, что вы пытаетесь сказать в последнем абзаце. Когда я пишу программы, я знаю, являются ли мои данные целыми числами, указателем, значением с плавающей запятой, char, std :: vector и т. Д. И т. Д. Я бы сказал, что писать код невозможно, если вы не знаете о том, в каком формате должны храниться ваши данные. В этом весь смысл программирования - манипулировать данными, поэтому, если вы «не знаете», как выглядят ваши данные, вам лучше понять это, прежде чем вы начнете вводить текст! – user3728501

+2

@ user3728501 Я знаю, как выглядят мои данные. К счастью, я не полностью сдерживаюсь машиной и могу думать более абстрактно: я могу знать, что что-то является целым числом, даже не имея в виду, является ли это 'u32' или' u64'. Я могу знать, что хочу искать пользователей для всех идентификаторов пользователей, не заботясь о том, что тип результата 'items.iter(). Map (User :: lookup)' is 'iter :: Map , fn (u32) -> Пользователь> '. И даже если мне нужно знать эти вещи в какой-то момент, мне не нужно постоянно знать * и подталкивать его к лицу каждого читателя. – delnan

+0

Я бы предположил, что это плохая практика - вы будете делать ошибки, если не знаете, какие ваши данные хранятся и как они будут себя вести. – user3728501

Смежные вопросы