Тип выражения &l
, с которым вы сопоставляете, равен &Option<i32>
, поэтому, если мы строгие, шаблоны должны быть &None
и &Some(x)
, и если мы используем эти шаблоны, тип x
действительно это i32
. Если мы опускаем амперсанд в шаблонах, как вы это делали в своем коде, сначала кажется, что шаблоны вообще не должны совпадать, и компилятор должен выдать ошибку, похожую на «ожидаемый вариант, найденная ссылка», и действительно это то, что компилятор делал до версии Rust 1.26.
Текущие версии Rust поддерживают «эргономику соответствия», представленную RFC 2005 , и теперь разрешено сопоставление ссылки на перечисление с шаблоном без амперсанда. В общем, если ваше выражение соответствия является только ссылкой, вы не можете перемещать какие-либо элементы из перечисления, поэтому сопоставление ссылки с Some(x)
эквивалентно сопоставлению с шаблоном &Some(ref x)
, то есть x
становится ссылкой к внутреннему значению Option
. В вашем конкретном случае внутренним значением является i32
, то есть Copy
, поэтому вам будет разрешено совпадать с &Some(x)
и получить i32
, но это невозможно для общих типов.
Идея RFC состоит в том, чтобы упростить правильную настройку амперсандов и ref
в шаблонах, но я не совсем уверен, действительно ли новые правила упростили вещи, или они добавили путаницы, создавая В некоторых случаях все волшебным образом срабатывает, что затрудняет понимание людьми истинной логики.