Rust: Проблема отслеживания для RFC 2126: уточнение и оптимизация путей и видимости

Созданный на 17 сент. 2017  ·  120Комментарии  ·  Источник: rust-lang/rust

Это проблема отслеживания для RFC «Уточнение и оптимизация путей и видимости» (rust-lang / rfcs # 2126).

Шаги:

Нерешенные вопросы:

  • Как нам подойти к миграции? Через запасной вариант, как предлагается, или через эпохи? Вероятно, лучше всего принять это решение с большим опытом, например, после того, как у нас в руках будет инструмент rustfix .

  • Последний синтаксис для абсолютных путей; здесь нужно провести больше байк-шэдинга в контексте, когда мы действительно можем опробовать различные варианты. В частности, есть некоторые реальные преимущества, имеющие как crate:: и extern:: пути, но в идеале мы могли бы сделать это в более сжатой форме.

B-RFC-approved C-tracking-issue E-needs-mentor T-lang WG-compiler-front

Самый полезный комментарий

Вот еще один случай, с которым я только что столкнулся, который сочетает в себе ключевое слово crate как в модификаторе видимости, так и в пути, что кажется даже более вероятным, чем экземпляр crate use crate... .

Текущий:

pub(crate) struct Bar {
    pub(crate) foo: ::Foo,
}

pub(crate) struct Baz(pub(crate) ::Foo);

С изменениями, связанными с этой проблемой отслеживания:

crate struct Bar {
    crate foo: crate::Foo,
}

crate struct Baz(crate crate::Foo);

Я лично считаю новый способ более запутанным, чем нынешний.

Все 120 Комментарий

Этот RFC имеет 4 отличительные особенности, но у нас по-прежнему есть только одна проблема с отслеживанием для всех из них. Можем ли мы, пожалуйста, не пихать вместе такие разрозненные функции?

@ retep998 Как объяснялось в обсуждениях RFC, эти функции связаны глобальными соображениями дизайна. Например, предоставление внешнего механизма для переименования ящиков частично вызвано окончательной отменой поддержки extern crate . Мы можем и будем обрабатывать различные аспекты по отдельности (и, вероятно, у нас будут некоторые перекрывающиеся ворота для опробования разных синтаксисов), но для обсуждения общего дизайна и стабилизации важно помнить о глобальной согласованности.

Наличие внешнего механизма для переименования ящиков - это то, что уже было желательно и необходимо в течение многих лет (https://github.com/rust-lang/cargo/issues/1311) и могло бы отлично работать самостоятельно, но вместо этого он используется как не более чем пешка в поддержку убийства extern crate .

В прошлом у нас не было проблем с наличием отдельных RFC для тесно связанных функций (на ум приходят RFC для repr(align(N)) и repr(packed(N)) ), но теперь мы заявляем, что изменение foo/mod.rs to foo.rs настолько тесно связаны с extern:: и crate:: что они должны быть в одном RFC и использовать одну и ту же проблему отслеживания?

Просто чтобы убедиться, что эта точка остается неизменной, поскольку это относительно тонкий аспект нерешенного вопроса синтаксиса: использование crate в качестве модификатора видимости, а также префикса пути вводит неоднозначность синтаксического анализа между crate ::absolute::path и crate::relative::path . Использование контекстного ключевого слова вводит ту же двусмысленность, и нет других зарезервированных ключевых слов, которые действительно имеют смысл в качестве модификаторов видимости.

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

Я бы не прочь разделить точку foo.rs / foo/mod.rs на отдельную проблему отслеживания, поскольку она действительно кажется независимой от изменений модификатора пути и видимости.

Что касается внешней клети переименования ... там уже отдельный вопрос для него? Это очень важно для изменения пути, поэтому я думаю, что тоже неплохо быть частью этого.

Несмотря на многочисленные дискуссии несколько недель назад относительно выбора crate в качестве модификатора видимости (а не префикса пути), я разочарован тем, что, хотя этот выбор ключевого слова был указан как «нерешенный вопрос» в RFC теперь явно забыли. Я сам и несколько других, которых я заметил, нахожу этот выбор запутанным, поскольку он не является прилагательным / модификатором и также может быть двусмысленным: означает ли crate часть общедоступного API ящика? Нет! Это означает, что local или internal или pub (lished) в ящик (поэтому я предпочитаю последние ключевые слова). Так что я не требую немедленных изменений, но, по крайней мере, признаю, что это нерешенный вопрос в этой проблеме отслеживания, чтобы об этом не забыли после стабилизации.

Замечательно, что этот редизайн модуля продвинулся так далеко, но в то же время важно, чтобы мы не промахнулись только для того, чтобы сделать «период имплементации», и в конечном итоге принять решения, не консультируясь с большинством пользователей Rust. И, к сожалению, я думаю, что люди, участвующие в обсуждениях Github RFC, не являются репрезентативными для всей пользовательской базы, поскольку огромное количество информации / комментариев / мнений может обескураживать. Так что с этим тоже нужно как-то разобраться.

Непонятно, чем закончилась реализация ...

@rpjohnst @ retep998 Я открыл новый RFC, чтобы обсудить foo.rs + foo/ а также предложить несколько улучшений этого RFC.

Изменить: я предлагаю открыть еще один RFC, чтобы обсудить crate в качестве модификатора видимости. Лично я хотел бы видеть обратное: pub(extern) добавляется и требуется для всех внешних опубликованных символов. Это сделало бы простой pub эквивалентом pub(crate) в следующую эпоху.

@rpjohnst

вводит неоднозначность синтаксического анализа между crate :: absolute :: path и crate :: relative :: path

В любом случае, не является ли код crate ::relative::path недействительным? Нельзя ли его отклонить при парсинге?

@ est31 Нет, это требует разрешения имен во время синтаксического анализа, чего мы определенно не хотим. Это одна из наиболее раздражающих частей синтаксического анализа C и C ++, которые имеют схожую двусмысленность в том, что a * b является умножением или объявлением, а a b(c, d); является объявлением переменной или прототипом функции.

Если мы когда-нибудь начнем разрешать зависимости и модули верхнего уровня с одним и тем же именем, даже путаница в разрешении имен с синтаксическим анализом нас не спасет - crate :: some :: item может быть crate -visible item от зависимости some или частный item от модуля верхнего уровня some .

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

Использование crate в качестве модификатора видимости, а также префикса пути приводит к неоднозначности анализа между crate ::absolute::path и crate::relative::path .

ИМО, это небольшая проблема, учитывая, что видимость полей структуры кортежа и «встроенные» абсолютные пути редки.
В настоящее время пути всегда жадно анализируются, поэтому имеет смысл, чтобы crate :: x :: y означало crate::x::y .
Если требуется обратное значение, можно использовать pub(crate) ::x::y или crate (::x::y) .

@rpjohnst @petrochenkov не могли бы вы поделиться примером кода, где pub ::relative::path - действительный код? Я не понимаю всей двусмысленности, потому что считаю, что один из двух случаев неверен.

Изменить: единственное место, где это может быть актуально, - это внутри макросов, когда вы сопоставляете квалификатор видимости + путь. Но это очень маленькая поломка, так что IMO приемлемо.

@ est31 Вы, кажется, ошиблись - дело не в относительных путях, они никогда не являются проблемой. Речь идет о создании AST до того, как вы узнаете, к чему относится любое из названий. Вот полный образец:

struct S(crate :: x :: y);

Учитывая, что вам пока не разрешено искать какое-либо из этих имен, как преобразовать эту строку символов в AST? Есть два возможных ответа. У одного есть личное поле типа y определенное в модуле x текущего ящика. Другой имеет crate -видимое поле другого типа y определенное на верхнем уровне зависимости x . Макросы не нужны.

@rpjohnst Вижу, спасибо за разъяснения. Это действительно двусмысленность.

@rpjohnst

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

    struct S(:: crate :: x :: y);

(обратите внимание на префикс :: для обозначения корневого "пространства имен")

Это согласуется с тем, как другие корневые пространства имен должны упоминаться в подмодулях (например, ::std::x::y ).

Я думаю, что простое устранение неоднозначности до crate -as-a-visibility было бы несколько удивительно. Но может быть хорошей идеей немного «канонизировать» этот обходной путь и обеспечить, чтобы crate:: всегда использовался с начальным :: (конечно, за пределами use s). Как вы указываете, это увеличивает симметрию с путями, подобными ::std::x::y , и оставляет форму без префикса для истинно относительных путей ( self:: / super:: / something_in_scope:: ).

Стоит ли нам это делать? Разрешение crate::x::y в путях, отличных от use делает crate своего рода волшебным, в то время как принудительное выполнение ::crate::x::y ограничивает его до того же уровня, что и зависимости, что мы и делаем в любом случае пытаешься намекнуть.

@rpjohnst

обеспечить, чтобы crate:: всегда использовался с начальным :: (конечно, вне использования)

Это может быть разумно, по крайней мере для начала (ничто не мешает расслабиться позже).

Я не поклонник синтаксиса use extern::bar::foo или use crate::bar::foo . Вроде очень шумно. Я бы предпочел для этого немного сахара. Я предлагаю для этого extern bar::foo .

Как насчет добавления еще одного неявного правила? Автоматически импортируйте extern crate в корневое пространство имен, сделайте более совпадающее выражение пути (я плохо говорю по-английски, пожалуйста, изучите мою точку зрения из следующего примера)

например

  1. Структура нашего проекта такая:

src
| --lib.rs
| --foo.rs
| --foo
| ---- | --bar.rs

  1. вы настраиваете зависимость в Cargo.toml, например
    [dependencies] serde = "3.0.0"

  2. мы добавляем мод bar в мод foo и добавляем мод foo в lib.rs,

  3. мы определяем функцию finlib в lib.rs, определяем функцию finfoo в foo.rs, определяем функцию finbar в bar.rs

Сделайте область видимости внешнего ящика модулем верхнего уровня в ящике, тогда мы сможем писать подобный код где угодно.

для полного / квалифицированного пути

::serde::Deserialize
::serde::x::y
::finlib                            // not ::crate::finlib
::foo::finfoo                   // not ::crate::foo::finfoo
::foo::bar::finbar           // not ::crate::foo::bar::finbar

относительный путь напишите так

serde::Deserialize      // no need to write `use serde`
serde::x::y                   // no need to write `use serde`
finlib                          
foo::finfoo                  
bar::finbar       

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

также мы можем использовать self::bar::finbar в foo.rs, чтобы избежать поиска имени.

Я не могу найти предыдущий поток, в котором это обсуждалось, но раньше компилятор работал таким образом, и это вызывало серьезные проблемы при разрешении имен. IIRC @pcwalton или @ arielb1, вероятно, знают больше.

Не самым простым решением этой неоднозначности было бы использование другого ключевого слова для модификатора видимости локального контейнера (например, замены pub(crate) ). Например, local , как много раз предлагалось ранее в предыдущих обсуждениях RFC. Тогда struct S(local :: x :: y) отличается от struct S(crate :: x :: y) .

Это просто вводит еще одну двусмысленность между <visibility> <absolute path> и <relative path starting with the new keyword> , поскольку новое ключевое слово должно быть контекстным.

@rpjohnst ах черт .. Но разве это не проблема, для решения которой были созданы эпохи? Например: в текущую эпоху мы просто используем pub(crate) , а затем, в следующую эпоху, вводим новое неконтекстное ключевое слово, которое является более «эргономичным».

@ neon64 да, но RFC утверждает, что для этого не нужна новая эпоха. Это утверждение, похоже, не соответствует действительности.

Это прекрасно - в настоящее время нет кода, который использует пути crate или crate:: , поэтому будет затронут только новый код. Пока мы выбираем разрешение и придерживаемся его, проблем с совместимостью нет.

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

В последнем предложении у нас есть crate:: для ссылки "в этом ящике" и self:: для ссылки "в этом модуле". Это немного непоследовательно и потенциально менее ясно, чем могло бы быть: с одной стороны, где self относится к «этому», это не является очевидным по своей сути «это что », и, наоборот, из-за того, что существует self:: что означает " этот модуль", можно сделать вывод, что crate:: могло означать " какой-то другой ящик", что является недоразумением, которое на самом деле упоминалось в потоке.

Одно из возможных решений - отказаться от self:: в пользу mod:: . Тогда у нас будет crate:: означающее «в ближайшем закрывающем ящике», и mod:: означающее «в ближайшем закрывающем модуле», и это будет ясно и согласованно. Мы также потенциально могли бы решить проблему, при которой невозможно квалифицированно ссылаться на элементы в области fn вообще , введя префикс fn:: , который, что неудивительно, означает "в ближайшем окружающем fn ". (Я не думал о том, есть ли смысл пойти дальше, а также иметь такие вещи, как trait:: или impl:: .)

@glaebhoerl , это интересное предложение. Лично я думаю, что я пришел к идее ввести новый синтаксис для абсолютных путей и отказаться от существующего. Я не уверен, как должен выглядеть этот синтаксис, но ниже я опишу одну возможность (которая, как мне известно, уже упоминалась ранее).

Представьте, что у нас есть следующая грамматика для путей:

Path = AbsolutePath | RelativePath
AbsolutePath = 
    | `@` ID? 
    | `@` ID? `::` RelativePath
    | `self` :: RelativePath
    | `super` :: RelativePath
RelativePath = ID (`::` ID)*

Согласно этой грамматике, можно ссылаться на вещи из других ящиков, начиная с @crate , например:

use <strong i="13">@std</strong>::collections::HashMap;

Можно сослаться на локальный ящик с помощью всего @ , например:

use @::something::in::my::crate;

use self::something остаются такими же, как сегодня, к лучшему или к худшему.)

В этом есть что-то приятное, так это то, что абсолютные пути полностью отличаются от относительных, а это значит, что теперь у нас есть желаемое свойство: можно копировать и вставлять путь из use в код, и это работает:

fn foo() {
    <strong i="24">@std</strong>::cmp::min(a, b) // OK
}

Сегодня это не так, что время от времени меня определенно смущает.

Мы также устраняем двусмысленность синтаксического анализа около crate , так что вы можете сделать pub Foo(crate @::MyType) или что-то еще, и это будет нормально работать.

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

Одного я не знаю, является ли @foo лучшим. Другой вариант, который, как мне кажется, работает и о котором я подумал, - это [] :

  • [std]::collections и [crate]::collections // []::collections кажутся слишком странными.

Я действительно не думаю, что мы должны вводить какие-либо новые сигилы только для путей. Введение :: в начале ::crate::foo достаточно для ответа на комментарий crate:: - это замена имени текущего ящика, а не префикса пути, такого как self:: .

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

Я не понимаю, что вы имеете в виду. Я не думаю, что какие-либо относительные пути начинаются с :: , не так ли?

@nikomatsakis @glaebhoerl, независимо от того, нравятся мне ваши предложения или нет (я действительно могу жить с обоими), можем ли мы придерживаться RFC? Это много раз обсуждалось, и я не думаю, что возобновление дебатов кому-то поможет. В общей сложности 82 человека прокомментировали ветку последнего RFC (до этого было довольно много дискуссий), и многие очень сильно отнеслись к этому. Я считаю, что было бы несправедливо по отношению к ним в этот момент внести изменения в предложение в последний момент, не давая им возможности пересмотреть это изменение.
Особенно я немного сбит с толку, потому что в # 44721 @nikomatsakis закрыл обсуждение этой функции с аргументом «давайте поговорим только о реализации, пожалуйста».

Обе нотации @ и [] были предложены (при этом я был сторонником обеих), но в конечном итоге они этого не сделали, по крайней мере, мое впечатление, из-за отрицательных ответов пользователей. .

Даже если вообще нет случаев, когда ведущий :: можно спутать с путем, который начинается с предыдущего идентификатора и имеет внутренний :: , он не очень отличается визуально.

Кроме того, это менее наводит на размышления. @ - лучшая мнемоника. С ведущим :: вы должны задаться вопросом, похоже ли это на пути к именам файлов, где ведущий / означает корень (если вы работаете в системе Unixy), или это стандартное сокращение, где нет ведущего вещь будет означать «мы не упомянули название, потому что оно относительное». Подумав на мгновение, вы можете увидеть, что первое имеет больше смысла, но дело в том, что это требует минутного размышления. @ (или что-то подобное) мгновенно различимы как для компилятора, так и для кодировщика, что упрощает мгновенное понимание того, что происходит.

Как начальный @ легче отличить от начального :: ? :: - это уже отработанный механизм как в Rust, так и в C ++!

@rpjohnst - Я сказал, как в той самой фразе, на которую вы отвечаете! @ отличается визуально. Чтобы расшириться: он прыгает на вас. Нет опасности путать ведущее и внутреннее позиционирование в вашей ментальной модели потока токенов.

@ - это совершенно новый токен, не имеющий никакого значения, и для его понимания потребуется гораздо больше, чем «мгновение размышлений». Запутать начальный :: с внутренним :: - это не проблема для начала - нет причин, по которым кому-то пришлось бы "на мгновение задуматься", чтобы отвергнуть идею о том, что ведущий :: может быть относительным путем.

@rpjohnst - Ваши утверждения верны при условии достаточного обучения тому, что означает :: (что обеспечивается опытом работы с C ++ или Rust). Я говорил об обучаемости и внутренней разнице. «Один и тот же символ, используемый в другом контексте» никогда не будет столь же различимым, как «уникальный символ».

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

@Ichoran : Я думаю, что добавление нового токена для определенной семантики ( @ ) в грамматику Rust - непростой шаг, и у меня есть небольшое подозрение, что мы слишком близки к тому, чтобы сделать это с @ может появиться во многих местах). Мне также интересно, как это влияет на восприятие сложности кода Rust. Для новичка, не привыкшего, например, к C ++, я считаю (но у меня нет исследований по этому поводу) Rust - это язык с довольно причудливой, пугающей нотацией. Одна из стратегических целей на этот год - оптимизировать обучаемость и, я полагаю, доступность Rust. Так что, возможно, мы должны учитывать это, представляя @ потому что интуиция подсказывает, что это будет выделяться в коде (что, на @rpjohnst ). Достаточно ли я понимаю, что я имею в виду?

(Не стесняйтесь исправлять или уточнять все, что я утверждал, поскольку у меня просто нет времени внимательно следить за обсуждением грамматики Rust.)

@ est31

Независимо от того, нравятся мне ваши предложения или нет (я могу жить с обоими), можем ли мы придерживаться RFC?

В принципе согласен. Я не очень хочу сейчас ввязываться в большие дискуссии - в конце концов, наступил срок! - но я действительно хотел поместить идею @ «где-то там», чтобы она кипела в фоновом режиме. Отчасти потому, что я склонен к забывчивости, а написание вещей помогает мне вспомнить их позже.

Я считаю, что на данном этапе правильнее всего поступить следующим образом:

  • Реализация RFC примерно так, как написано.

    • Мы можем захотеть, например, принять предложение @rpjohnst о ::crate для абсолютных путей, просто чтобы устранить неоднозначность синтаксического анализа, потому что это похоже на очень маленькую дельту и фактически увеличивает согласованность в целом.

  • Наберитесь опыта в его использовании.
  • Пересмотрите конструкцию, помня об альтернативах, которые были обнародованы к тому времени, и примите окончательные решения по стабилизации.

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

РЕДАКТИРОВАТЬ: Кроме того, я знаю, что @ и [] были подняты ранее, хотя я не помню, упоминалось ли ранее обозначение @::foo как относительное к текущему ящик. Так что я не претендую на авторство идеи.

OTOH, идея, о которой я упоминал, ранее не поднималась и является не столько модификацией RFC, сколько его расширением. Кроме того, «Последний синтаксис для абсолютных путей; здесь нужно сделать больше байк-шеддинга в контексте, где мы действительно можем опробовать различные варианты». явно указан как нерешенный вопрос в теле проблемы. Я согласен с тем, что в целом нам следует избегать повторных судебных разбирательств по принятым RFC, но я не чувствую, что эта ситуация сопоставима с той, которая была у нас, например, с включенными диапазонами (тьфу).

См. Также эту ветку обсуждения:

https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678

Добро пожаловать в очередной эпизод Великого приключения модулей! Когда мы в последний раз встречались, наши отважные искатели приключений наконец-то прибыли в сказочную страну, приняв RFC # 2126. Там они взяли короткую передышку и приготовились начать Импл Период. За это время была проделана большая работа, и действительно были реализованы контуры модульной системы. Но вот осталось еще несколько мелких вопросов, которые нужно было решить… и это подводит нас к этой дискуссии.

Проще говоря: в течение периода имплементации мы добились значительного прогресса в реализации RFC «Уточнение и оптимизация путей и видимости» (вместе с рядом связанных RFC). Фактически, мы добились почти слишком большого прогресса - мы реализовали несколько различных вариантов, и я хотел бы начать обсуждение того, что мы действительно хотим.

Я хотел бы когда-нибудь стабилизировать эту отличную работу =), а для этого нам потребуется выбрать один из вариантов ... отсюда и ветвь.

Лично я поклонник синтаксиса @ упомянутого @nikomatsakis. Это кратко и достаточно понятно. Нам нужно будет ввести здесь какой- то новый синтаксис, поэтому лучше использовать специальный символ, чем зарезервированное имя, например crate (тьфу).

Похоже, теперь мы можем заняться вторым внешним указателем, особенно учитывая, что https://github.com/rust-lang/cargo/issues/1311 теперь решен (фактически, он уже должен быть закрыт). Возможно, я смогу решить эту проблему с помощью небольшого наставничества и решения по синтаксису @ против crate . Мысли?

Добавлены проблемы с отслеживанием двух нереализованных линтов.

Мне пришло в голову, что у нас есть небольшая проблема совместимости: если мы хотим, чтобы extern crate стало неявным, для выполнения этой работы требуется критическое изменение - extern crate заставляет ящики связываться; что может вызвать ошибки, если вы укажете дополнительные ящики в Cargo.toml, но не lib.rs, которые не связаны между собой чисто (например, panic = размотать ящики с panic = abort или ящики, которые экспортируют один и тот же символ). Мы определили, что это беспроблемная поломка?

Мне пришло в голову, что у нас есть небольшая проблема совместимости: если мы хотим, чтобы extern crate стал неявным, для выполнения этой работы требуется критическое изменение - extern crate заставляет ящики связываться; что может вызвать ошибки, если вы укажете дополнительные ящики в Cargo.toml, но не lib.rs, которые не связаны между собой чисто (например, panic = размотать ящики с panic = abort или ящики, которые экспортируют один и тот же символ). Мы определили, что это беспроблемная поломка?

Единственное решение, которое я видел до сих пор, - это неявно связывать ящик только при импорте чего-либо из этого ящика, однако здесь все еще есть некоторые проблемы. Существует множество способов, которыми ящики могут предоставлять функциональные возможности, помимо простого экспорта символов ржавчины для импорта, таких как связывание в определенной нативной библиотеке или экспорт символов #[no_mangle] для разрешения некоторых зависимостей в нативной библиотеке. После удаления extern crate единственный способ принудительно подключить такой ящик - это заставить его экспортировать символ ржавчины плацебо, который будет импортирован по мере необходимости. Я не знаю, кто подумал, что было бы лучше заставить людей использовать такой обходной путь вместо того, чтобы придерживаться extern crate .

Да, мы явно используем этот шаблон в Firefox - есть ящик верхнего уровня gkrust который просто содержит операторы extern crate для ящиков, которые необходимо связать (они открывают функции extern C, написанные на Rust, которые вызывает Firefox)

Вы все еще можете заставить его работать, требуя от людей use cratename; в lib.rs, чтобы заставить это работать.

Как насчет наличия для этой цели атрибута #![link_crates(stylo,webrender)] ? В отличие от extern crate , он не добавлял ящик в дерево имен. Присвоение ему нового имени ясно укажет читателям, что вы включаете ящики только для связывания и что оператор не следует удалять, а extern crate следует.

Но это решает противоположную проблему?

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

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

Как насчет наличия для этой цели атрибута #! [Link_crates (stylo, webrender)]? В отличие от extern crate, он не добавлял ящик в дерево имен.

А как насчет ящиков, которые можно использовать либо как ящики только для ссылок, либо как ящики с символами Rust, либо и то, и другое?

@whitequark, если вы используете символы из этих ящиков, вы получите ссылку бесплатно, как это происходит уже сейчас. Атрибут будет на сайте использования, поэтому вы, как пользователь, решаете, как использовать ящик.

@Manishearth

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

Нет. Я недостаточно хорошо сформулировал свое предложение. Я хочу сохранить ту часть, где use cratename::item; имеет тот же эффект, что и link_crates . Функцию link_crates следует использовать только в том случае, если вам не нужен какой-либо элемент из ящика, но нужна связь. Если вы импортируете какие-либо элементы из ящика, вы получите ссылку, как это было предложено в RFC.

Я просто не думаю, что наличие use cratename; в вашем коде для этой цели - это хорошо, потому что это сбивало бы с толку линты и (что наиболее важно) читателей / писателей кода, и поэтому думаю, что должна быть специальная функция для этого законного (но редко) вариант использования.

@ est31 Bikeshedding синтаксиса для link_crates , вместо того, чтобы использовать его как атрибут, почему бы нам не сделать что-то вроде extern crate foo; ?

@ retep998
Хорошая идея! :улыбка:
https://github.com/rust-lang/rfcs/pull/2166 даже ввел extern crate foo as _; чтобы избежать добавления имени контейнера в область действия / модуль для ящиков, предназначенных только для связывания.

@ est31 Bikeshedding синтаксиса для link_crates, почему бы нам не сделать что-то вроде extern crate foo ;?

Однако все дело в том, чтобы в конечном итоге избавиться от синтаксиса extern crate .

@alexreg Дело в том, чтобы в общем случае он не

@SimonSapin Но, двигаясь вперед, если это будет

Я все еще думаю, что здесь должно быть достаточно use foo или use foo as _ , правда

Согласитесь с @Manishearth.

Обобщая мой взгляд на extern crate; :

Преимущества:

  • extern crate дает вам полный список использованных ящиков прямо в верхней части вашей библиотеки. Теперь с нормальными обрешетками это не так актуально как есть Cargo.toml, но если у вас есть примеры это очень полезно , так как это дает вам список ящиков для импорта. Подумайте, что, если ваши примеры просто импортируют подмножество ваших dev-зависимостей? Это дает большие преимущества при попытке выяснить API нового ящика, также как и преимущества обучаемости. С другой стороны, вы можете упомянуть, что extern crate может появиться в любом месте ящика, поэтому список не должен быть исчерпывающим, но для примеров это менее актуально. Мы всегда можем изменить внешний ящик так, чтобы он работал только в корне ящика, если захотим.

Недостатки:

  • extern crate - это незначительное раздражение, так как это означает, что при добавлении ящика нужно набирать больше материала. Я думаю, что это причина того, почему многие люди против extern crate но для меня это не мотивирующая причина.
  • Я вижу, что extern crate является частью сделки: мы отказываемся от extern crate но получаем различимость между импортом из собственного ящика и импортом из внешнего ящика. Это гораздо более полезная функция, которая перевешивает недостатки обучаемости IMO с помощью примеров / тестов кода. Это мотивирующая причина, по которой я согласен с удалением extern crate .

extern crate дает вам полный список использованных ящиков прямо в верхней части вашей библиотеки. Теперь с обычными ящиками это не так актуально, как есть Cargo.toml, но если у вас есть примеры, это очень полезно, поскольку дает вам список ящиков для импорта.

Я не понимаю, какое отношение это имеет к обсуждаемому здесь; это аргумент против уже объединенного RFC.

@Manishearth Я больше отвечал на @ retep998, который как бы предлагал сохранить внешний ящик. И нет, пункт не является незаконным или неуместным только потому, что он противоречит уже объединенному RFC. Нужно размышлять и знать преимущества и недостатки описаний. Мы все еще можем, например, удалить внешний ящик из lib.rs но оставить его за hello_world.rs из соображений эргономики и удобства обучения (для пользователей библиотеки, а не ее авторов).

Это не имеет значения, потому что обсуждаемая вещь (в комментарии Питера, на который вы отвечаете) - это ящики только для ссылок; которые являются достаточно нишевым вариантом использования, так что «перечислить все внешние ящики вверху» будет незначительным преимуществом. Особенно, если у вас есть зависимости, которые также _не_ ссылки только для ящиков (раньше это было неверно для Firefox, но теперь это так).

Если ваша точка зрения является более общей о том, что неявная вещь extern crate не применяется к тестам (и не конкретно к ящикам только для ссылок), это интересный момент, но я действительно не согласен с ним, потому что это будет больше сбивает с толку, когда он используется только в половине кода.

Итак, если я не ошибаюсь, единственная оставшаяся точка реализации здесь - # 48719. Кто-нибудь сейчас этим занимается? Если нет, я могу попробовать ...

Да, мы пробуем вещи в # 50260

В субботу, 28 апреля 2018 г., 9:15 Александр Регейро [email protected]
написал:

Итак, если я не ошибаюсь, единственная оставшаяся точка реализации здесь - это

48719 https://github.com/rust-lang/rust/issues/48719 . Кто-нибудь

решать это сейчас? Если нет, я могу попробовать ...

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-385187379 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/ABivSMyg6L4nQ1O7nMcvY4JCGjWKRiq3ks5ttJWhgaJpZM4PaPWi
.

48722 готово. @Manishearth, не могли бы вы обновить OP, пожалуйста :)

@ mark-im @Manishearth https://github.com/rust-lang/cargo/issues/1311 также завершено, поэтому, возможно, стоит поменять этот пункт на флажок и поставить галочку . Мне любопытно: каков подход, когда Cargo не используется и идет вперед? (Не то чтобы здравомыслящие люди избегали Cargo ...)

@alexreg Механизм, который Cargo использует, чтобы сообщить rustc о переименовании ящика, одинаково доступен для людей, не использующих Cargo: --extern name_rustc_sees=path_to_dep.rlib .

Похоже, мы скоро завершим весь этап реализации - когда фактически появится https://github.com/rust-lang/rust/pull/47992 . Я что-нибудь упускаю? С радостью помогу продвинуться в этом, если еще остались какие-то мелочи.

Да, уже в пути. Мне нужно завершить то, что я, скорее всего, сделаю раньше
Следующая неделя.

Вт, 3 мая 2018 г., 19:51 Александр Регуэйро [email protected]
написал:

Похоже, мы скоро завершим весь этап реализации - когда

Фактически, 47992 https://github.com/rust-lang/rust/pull/47992 приземляется. Являюсь

Я что-то упускаю? Рад помочь продвинуться в этом, если есть какие-то биты и
бобов осталось сделать.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-386494018 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/ABivSDYFonDWvxZEdxWXoykroaL2mJPxks5tu8I_gaJpZM4PaPWi
.

@Manishearth Хорошие вещи.

@aturon с https://github.com/rust-lang/rust/pull/50260 приземлился, все ли реализовано?

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

Поскольку это такое существенное изменение, может быть, следует обновить RFC?

RFC обычно не обновляются; они не окончательная спецификация. Они
инструмент достижения консенсуса.

В понедельник, 18 июня 2018 г., в 21:43, Кто? Мне?! [email protected] написал:

Поскольку это такое существенное изменение, может быть, следует обновить RFC?

-
Вы получаете это, потому что подписаны на эту беседу.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-398247665 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AABsij-Iwwb7vf4qBrsq9KFFqhuIbkVBks5t-Fc3gaJpZM4PaPWi
.

@ mark-im Этот пост с дискурсом остается в духе RFC. Сравните резюме RFC с этим сообщением, оно в основном то же самое, за исключением мелких деталей. Были RFC, в которых команда решила внести совершенно другие изменения, но это не одно из них.

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

🔔 🔔 Обратите внимание, что предварительная версия выпуска начала

@aturon Последнее обновление и последнее собрание рабочей группы модуля привели к публикации https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678/205 , в которой конкретно говорилось: « сузился до единого основного предложения с двумя вариантами ". Насколько мне известно, это все еще было правдой. У меня создалось впечатление, что nightly реализовал оба, с помощью флагов функций, чтобы поддерживать эксперименты с обоими.

Кажется, что издание выбрало один из двух вариантов, выбрало его для поддержки без флагов функций и задокументировало это в руководстве по редакции. Где это обсуждалось? Потому что, насколько я могу судить, ни рабочая группа модуля, ни команда lang не участвовали в этом.

Пожалуйста, посетите https://internals.rust-lang.org/t/relative-paths-in-rust-2018/7883, чтобы узнать о новом предложении, основанном на предварительной версии 2018 года. В частности, это предложение обеспечивает большую согласованность и единообразие между корневым модулем и подмодулями и использует одно и то же разрешение имен как в операторах use и при прямом использовании путей в коде.

Привет, только мои 2 цента на ::some::path против crate::some::path - я предпочитаю последнее, в основном потому, что его легче читать как обычный английский и не оставляет сумасшедших левосторонних знаков препинания.

Пожалуйста, посмотрите и оставьте отзыв здесь!

Надеюсь, вы это имели в виду. После просмотра большого изменения ящика фьючерсов, в котором все pub(crate) были заменены на crate , я более убежден, что использование crate как при импорте, так и в качестве видимости модификатор кажется неестественным и сбивающим с толку.

crate enum Either<T, U> {
    A(T),
    B(U),
}

Меня особенно сбивает с толку, когда они используются вместе:

crate use crate::foo;

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

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

@seanmonstar С учетом предлагаемых дополнительных изменений в модульной системе в следующем предварительном выпуске, я ожидаю, что crate::foo станет более редким, а crate use crate:: кажется особенно редким явлением.

С модульной системой в первоначальной предварительной версии 2018 вам нужно было бы написать crate:: даже для ссылок, находящихся глубже в вашем ящике. С предложенной модульной системы, вам нужно всего лишь crate:: за ссылки в вашем ящике (например, от foo.rs к lib.rs, или из Foo / bar.rs в foo.rs), но не для ссылок вниз в вашем ящике (например, от lib.rs к foo.rs, или от foo.rs к Foo / bar.rs). И, как правило, я бы ожидал, что реэкспорт (будь то через pub use или crate use ) будет реэкспортировать что-то из более глубокого модуля в модуль более высокого уровня, а не наоборот.

В общем, я был бы удивлен, увидев crate use crate::foo; .

И все же в проекте, над которым я работаю, у меня есть именно такой сценарий. У меня есть модуль, который содержит несколько «общих» помощников, а затем еще один модуль, определяющий базовый признак + комбинаторы, и, поскольку они используют пару общих помощников, я реэкспорт, чтобы помочь себе в других частях ящик:

В настоящее время:

// in filter/mod.rs
pub(crate) use ::generic::{Combine, Func};

// in filters/foo.rs
use ::filter::{Filter, Func};

Линт попросит меня изменить это на:

// in filter/mod.rs
crate use crate::generic::{Combine, Func};

Итак, я не пытался придумать гипотезу, с которой никто никогда не столкнется. Это реально.

Я полностью согласен с @seanmonstar. Давайте не будем перегружать это ключевое слово, если это не нужно (а мы этого не делаем).

Да, вы правы в том, что реэкспорт _ обычно_ пузырится, но, как подчеркивает Шон, реэкспорт _ боковым_ тоже имеет значение. Это то, что я подумываю сделать и для ящика сервомедиа, так как файлы разделены довольно хорошо, но это просто означает много общего импорта во всех реализациях наших узлов.

Можно ли будет продолжать объявлять, что используется в модуле и, возможно, потребовать явного использования, возможно, в качестве атрибута ящика? Я предпочитаю знать, просматривая исходный файл, что в нем находится. Наличие пары строк импорта корневого уровня в начале исходного файла помогает дать некоторый контекст для того, что на самом деле происходит внутри него, вместо того, чтобы просто неявно иметь все внешние зависимости в области видимости, и очень помогает при рефакторинге.

Попробовав преобразование на одном из моих ящиков, я хотел упомянуть, что, как и некоторые другие, которых я видел, говоря об этом, я не уверен, что использование crate в качестве модификатора видимости вместо pub(crate) является улучшение. Я рассуждаю здесь о том, что прозвище ящика довольно широко используется, и простое размещение его перед предметами делает его немного беспорядочным (это напоминает мне суп с ключевыми словами, который вы используете в некоторых языках, например, в Java public static void main() - по крайней мере, в конце Rust есть возвращаемый тип). pub(crate) по крайней мере сохраняет pub чтобы было более очевидно, что crate имеет дело с видимостью в этом контексте.

Вот еще один случай, с которым я только что столкнулся, который сочетает в себе ключевое слово crate как в модификаторе видимости, так и в пути, что кажется даже более вероятным, чем экземпляр crate use crate... .

Текущий:

pub(crate) struct Bar {
    pub(crate) foo: ::Foo,
}

pub(crate) struct Baz(pub(crate) ::Foo);

С изменениями, связанными с этой проблемой отслеживания:

crate struct Bar {
    crate foo: crate::Foo,
}

crate struct Baz(crate crate::Foo);

Я лично считаю новый способ более запутанным, чем нынешний.

Когда я впервые прочитал RFC о преобразовании pub(crate) в crate я подумал, что это звучит как легкая задача. pub(crate) выглядит очень странно по сравнению с остальным синтаксисом Rust в этой области.

Но...

После преобразования небольшой игры Piston в Rust 2018 и непосредственного ознакомления с ней я должен признать, что с пониманием отношусь к повсюду разбросаны всего лишь crate что меня раздражало. Я не уверен, привыкну ли я к этому естественным образом со временем или нет.

Как уже говорили другие, кажется, что ключевое слово означает что-то совсем другое в обоих контекстах.

use crate::menu::{Sound, Volume};

crate mod color;

...

/// A type for storing text and an associated color it should
/// be drawn as.
crate struct ColoredText {
    crate color: types::Color,
    crate text: &'static str,
}

Я хочу прояснить, что мне действительно нравится остальная часть этого предложения (обновления системы модулей).

Я сочувствую, что pub(crate) кажется немного деспотичным и к тому же странным, но в то же время чистые crate кажутся немного неуместными.

Можем ли мы просто рассмотреть здесь другое ключевое слово вместо повторного использования crate ?

@ neon64 Предложил internal что звучит разумно, но могут быть и другие. Поскольку мы можем добавлять ключевые слова в Rust 2018, у нас есть возможность это рассмотреть.

internal мне кажется тяжелее pub(crate) . Это не короче, и это новое ключевое слово.

Как насчет int ? :П

Внутренний ( ins ), внутренний ( int ), защищенный ( pro ), локальный ( loc ), секретный ( sec ), inner ( inn ) ключевому слову crate существует множество альтернатив.

Будет ли int сбивать с толку разработчиков C / C ++? (Целочисленное ключевое слово)

Как программист, когда вы видите pub, вы относитесь к нему как к общедоступному, если вы хотите ввести другой уровень видимости, вам нужно, чтобы он был прилагательным, чтобы оставаться последовательным. Насколько я помню, паб изначально означал публикацию, и в обоих случаях паб (ящик) кажется более естественным. Ящик - просто странное ключевое слово для этого.
Думаю, лучше оставить pub (crate) как есть или добавить аббревиатуру от прилагательного.

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

Лично я просто не вижу проблемы с pub(crate) . Синтаксис на первый взгляд ясен и недвусмысленен и соответствует настоящему Rust. Я не думаю, что вам нужно набирать это достаточно часто, чтобы 5 дополнительных нажатий клавиш были проблемой.

@UtherII

Причина, по которой нам нужно короткое имя для pub(crate) заключается в том, что многие (возможно, даже большинство ) текущие использования pub будут заменены им.

В Rust 2018 использование pub для эффективных приватных элементов (потому что они появляются в приватных модулях) будет предупреждением. Вместо этого следует использовать pub(crate) для таких предметов. Это соглашение улучшит читаемость кода: элемент виден для других ящиков тогда и только тогда, когда он помечен как pub , тогда как в настоящее время его видимость для других ящиков может быть не очевидна с первого взгляда.

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

Поскольку руководство по редакции предлагает людям оставлять здесь отзывы, я решил это сделать.

Я не против crate :: или :: для доступа к элементам из корня crate. :: это то, что уже является синтаксисом, поэтому, если возможно иметь оба crate :: и ::, я думаю, что следует использовать оба. Насколько я понимаю, новая предлагаемая система ящиков относительно путей по существу эквивалентна старому синтаксису с той лишь разницей, что вам больше не нужно использовать ключевое слово extern, и вещи более доступны, чем необходимость их использования явно в подмодулях они по существу неявно импортируются повсюду.

Единственное другое дополнение, похоже, заключается в том, что вы запускаете корень crate с crate ::, а не ::. Я предпочитаю начинать его с просто ::, так как это согласуется с тем способом, которым я его изначально изучил, однако я вижу людей, которые еще не изучили модульную систему, но находят запуск ее с crate :: более интуитивно понятным. Почему бы не разрешить обе формы синтаксиса? Есть ли какая-то причина, по которой невозможно иметь их обоих? Если можно поддержать обоих, я полностью поддерживаю их обоих. Если можно поддерживать только один, я больше склоняюсь к :: точно так же, как это то, к чему я привык, хотя новичкам может быть проще выучить его как crate ::, и я могу тривиально обновить свое понимание этого быть таким, возможно, моя мотивация эгоистична.

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

Как #[path] должен работать с вложенными модулями в Rust 2018? (https://github.com/rust-lang/rust/issues/35016#issuecomment-409185342)

IIUC, прямо сейчас, учитывая два файла src/lib.rs и src/bar.rs , нет X который можно было бы заменить на:

mod foo {
    #[path = "X/bar.rs"]
    mod bar;
}

так что модуль bar.rs будет найден, потому что путь к bar.rs всегда будет src/foo/X/bar.rs что недопустимо, потому что каталог foo не существует.

Поскольку мы ищем хорошее имя для замены pub(crate) а основная команда все еще ищет отзывы, я хотел бы поделиться своим опытом и предложить предложение.

В одном ящике, который я написал, я нашел, что набирать везде pub(crate) приводило меня в бешенство. Поэтому я просто сократил его до pub и непреднамеренно экспортировал множество символов, которые не нужно было видеть за пределами ящика. Ой. 😛 (В моем конкретном случае это не проблема, потому что ящик является внутренним и неопубликованным, но все же! Удобство важнее правильности.) Так что да, я твердо уверен, что нам нужно что-то лучше, чем гибрид из двух ключевых слов, чтобы обеспечить видимость на уровне ящика. .

Но я не верю, что crate - подходящее ключевое слово для этого (см. Выше отзывы других по этой теме), и я чувствую, что некоторые другие предлагаемые ключевые слова как бы упускают суть, подходя к проблеме с точки зрения корня обрешетки; проблема заключается в перспективе модуля, то есть в конкретной строке кода, содержащей ключевое слово. Другими словами, код не пытается обеспечить «локальность ящика», он пытается экспортировать ссылку из модуля, в котором она определена.

В этом смысле мне нравится ключевое слово export (даже если его можно спутать с extern , но, может быть, это спорный вопрос, поскольку extern crate мертв?) export struct Foo; выглядит очень читабельным и согласуется с некоторыми другими языками (иш). Мне не удалось найти упоминания о export в качестве ключевого слова ни в этом RFC, ни где-либо еще. Так что это тоже самое.

Для полноты он охватывает варианты использования, предложенные @seanmonstar , @johnthagen и др .:

export use crate::generic::{Combine, Func};

// Or even better using relative paths
export use ::generic::{Combine, Func};
export struct Bar {
    export foo: crate::Foo,
}

export struct Baz(export crate::Foo);
use crate::menu::{Sound, Volume};

export mod color;

// ...

/// A type for storing text and an associated color it should
/// be drawn as.
export struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}

С учетом всего сказанного, я за убийство pub(crate) огнем. Я даже предпочитаю crate , FWIW.

@parasyte Проблема, которую я вижу с export заключается в том, что ее можно спутать с «этот ящик экспортирует ____» (для чего и предназначен pub ), но я понимаю, что вы отстаиваете Другой точки зрения.

Похоже, что большинство людей согласны с тем, что pub(crate) не идеален, и многие высказывали опасения, что существительное ключевое слово crate , которое теперь используется в других контекстах, может вызывать раздражение в качестве замены. Убедившись, что мы полностью учли другие (потенциально новые) ключевые слова, кажется, было бы очень полезно потратить время, прежде чем Rust 2018 зафиксирует это в камне.

Я не слышал никаких «официальных» отзывов, но это все еще открыто для обсуждения?

В интересах введения еще нескольких слов в соответствии с предложением @johnthagen, что export больше похоже на pub чем на pub(crate) ):

shared use ::generic::{Combine, Func};
shared struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}
global use ::generic::{Combine, Func};
global struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}

Мы также могли бы пойти по стопам Java и использовать что-то вроде protected , но я не уверен, что это особенно легко интуитивно понять. Также есть local (в смысле crate-local), но я думаю, что global на самом деле менее вероятно, чтобы запутать (например, local может быть _file_-local).

Как люди отнесутся к pub(cr) или даже к cr ?

Использование crate кажется слишком хорошим, чтобы отказаться от него. Это уже ключевое слово, его предыдущее использование в extern crate больше не используется. Другое его использование уже связано с видимостью pub(crate) .

Если вы немного прищуриваетесь, использование прилагательного crate не так уж сбивает с толку. Такие слова, как «дом», можно использовать как прилагательные. IANAEnglishProfessor.

Я думаю, что реэкспорт видимого в ящике предмета - не проблема. Лично я только когда-либо повторно экспортировал элемент в прямом родительском элементе модуля, который его определяет, что означает, что вы (вероятно) хотите использовать self вместо crate (несмотря на то, что в случае seanmonstar с организацией кода ). Например.

    mod detail {
        crate struct Foo;
    }

    crate use self::detail::Foo;

Использование crate в качестве видимости в сочетании с абсолютным путем к типу (снова используя пример seanmonstar) выглядит более проблематичным: crate struct Foo(crate crate::Bar); в отличие от pub(crate) struct Foo(pub(crate) ::Foo); . Я надеюсь, что эта конструкция не пользуется популярностью, и поэтому переход не приведет к созданию супа из ящиков. Пользователи могут избежать этого, явно импортировав:

use crate::Bar;

crate struct Foo(crate Bar);

Мне нравится предложение share или что-то в этом роде. give , provide , deliver , offer , serve , post , forward .. . Если это должно быть прилагательное, все они могут быть преобразованы с помощью суффикса: shared , givable , providable и т. Д.

Если на мгновение остановиться на JavaScript, то в ES6 даже нет концепции пакета по сравнению с модулем, встроенной в язык. Есть только модули. Ключевое слово export в ES6 всегда экспортирует ссылку из модуля; затем до другого модуля import эта ссылка по пути, если он хочет ее использовать.

Это не сильно отличается от pub и use соответственно. и я предполагаю, что здесь возникнет некоторая путаница с использованием ключевого слова export . pub(crate) на самом деле своего рода ниша. Вот почему раньше я просто использовал pub . ; (

Проблема с модификатором видимости crate перенесена в # 53120. Дальнейшие обсуждения и решения должны продолжаться там.

Проблема с изменениями mod.rs вынесена в # 53125. Дальнейшие обсуждения и решения должны продолжаться там.

Проблема устаревания extern crate а также наличия use crate_name::foo и crate_name::foo Just Work ™ вынесена на https://github.com/rust-lang/rust/ вопросы / 53128. Дальнейшие обсуждения и решения должны продолжаться там.

Проблема выбора системы путей к модулям вынесена на

Выделив все биты из этого выпуска в отдельные выпуски; Я закрываю это.

@Centril : https://doc.rust-lang.org/unstable-book/print.html#extern_prelude ссылки здесь. Где это обсуждается? Если эта информация действительно отсутствует, не могли бы вы добавить ее в OP?

@ sanmai-NL, можешь освежить мою память о том, что это была за "внешняя прелюдия"?

Если это просто возможность делать use some_crate::foo::bar; тогда это должно быть https://github.com/rust-lang/rust/issues/53128.

Некоторые из них обсуждаются в https://github.com/rust-lang/rust/issues/54230.

@ sanmai-NL Я считаю, что проблема в основном связана с диагностикой.

extern_prelude - это crate_name::foo::bar за пределами use (импорт) путей.

@Centril

Можете освежить мою память о том, что это была за "внешняя прелюдия"?

В общем, «прелюдия» в настоящее время используется для всех имен, которые входят в область действия всего ящика и не привязаны к конкретному модулю. (На самом деле их очень много.)

@petrochenkov Так что же по этому поводу "внешняя" прелюдия?

@alexreg
Ящики, переданные с --extern , охватывают весь ящик, но не прикреплены к какому-либо конкретному модулю.

Было бы здорово, если бы эти частички информации, независимо от их изменчивости, были записаны в каком-нибудь официальном источнике документации. Esp. если есть внешние упоминания о концепции, например, в книге Unstable. Однако я не говорю, что разработчики, реализующие эти концепции, должны это делать.

@petrochenkov Спасибо, имеет смысл.

Выделив все биты из этого выпуска в отдельные выпуски; Я закрываю это.

@Centril Проблемы с отслеживанием в текущей бета-версии, ссылка здесь. Вы бы обновили исходный комментарий самой последней информацией, чтобы людям не приходилось писать комментарии по отдельности?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги