Rust: (Modul) Masalah pelacakan untuk `crate` sebagai pengubah visibilitas

Dibuat pada 6 Agu 2018  ·  91Komentar  ·  Sumber: rust-lang/rust

Ini adalah masalah sub-pelacakan untuk RFC "Klarifikasi dan perampingkan jalur dan visibilitas" (rust-lang/rfcs#2126)
berurusan dengan pertanyaan crate sebagai pengubah visibilitas.

Pertanyaan yang belum terselesaikan:

  • [ ] Bagaimana cara kita mengurai struct Foo(crate ::bar) ?
A-visibility B-RFC-approved B-RFC-implemented B-unstable C-tracking-issue T-lang

Komentar yang paling membantu

Saya pribadi setuju dengan menulis pub(crate) , maksudnya tampak sangat eksplisit.
Contoh yang diberikan oleh @johnthagen sangat menyakitkan untuk dilihat(menggunakan 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,
}

crate mod color; terutama tampak membingungkan, Anda pasti perlu sedikit memikirkan apa yang terjadi di sana.

Semua 91 komentar

Komentar tentang crate sebagai pengubah visibilitas:

Mengurai ambiguitas

Tidak wajar / Kebingungan / Bukan perbaikan

Sebuah ide bagus

pub(extern) sebagai gantinya

Gudang sepeda

Pratinjau awal

utas khusus

Secara pribadi, saya sangat mendukung crate sebagai pengubah visibilitas dan saya membagikan komentar @stepancheg di sini . Saya pikir kita harus mendorong visibilitas yang lebih kecil dan lebih ketat dan crate melakukan hal itu.

Saya pribadi setuju dengan menulis pub(crate) , maksudnya tampak sangat eksplisit.
Contoh yang diberikan oleh @johnthagen sangat menyakitkan untuk dilihat(menggunakan 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,
}

crate mod color; terutama tampak membingungkan, Anda pasti perlu sedikit memikirkan apa yang terjadi di sana.

Beberapa contoh ini sangat C- static -esque- terkait secara intuitif tetapi sangat berbeda.

Contoh karena @johnthagen tidak terbaca dengan buruk bagi saya. Sebenarnya, itu terbaca secara alami dan saya sangat menyukai simetrinya. Ini indah dengan cara.

Jika keterbacaan:

crate struct ColoredText {
    crate color: types::Color,
    crate text: &'static str,
}

menjadi masalah; kemudian IDE/editor yang memahami sintaks Rust dapat menyorot token crate di posisi berbeda dengan warna berbeda. Itu harus menjernihkan perbedaan dengan baik, saya pikir.

crate sebagai pengubah visibilitas jelas aneh: ia menggunakan kata kunci yang sangat spesifik untuk sesuatu yang tidak spesifik untuk karat. Kotlin & C# menggunakan internal untuk ini.

Saya pribadi ingin menggunakan kembali pub untuk crate-visible , dan mencari sintaks yang lebih jeritan untuk terlihat dunia, seperti pub* atau pub! .

Ini telah dibahas sebelumnya, tetapi saya pikir akar masalah yang saya lihat adalah:

  1. crate adalah kata benda . Saya pikir pub(crate) panjang dan tampak aneh, jadi saya sepenuhnya mendukung menggantinya dengan something , tetapi memiliki kata sifat publik yang terkait dengannya, jadi secara tata bahasa mengalir lebih baik.
  2. crate sekarang digunakan sebagai jangkar untuk impor "peti ini", yang berarti sesuatu yang berbeda dari "di mana pun ini ditentukan, itu juga diekspor secara terlihat dari peti ini"
// Here `crate` means the root of this crate.
use crate::menu::{Sound, Volume};

// Here, `crate` means: export crate::game::color
// The `crate` is referring to `color`, not the root.
crate mod color;

...

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

Dibandingkan dengan contoh, menggunakan @matklad 's internal dari Kotlin/C#.

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

internal mod color;

...

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

Saya tidak mengatakan internal adalah kata kunci yang tepat (Rust suka singkatannya yang sangat pendek, dan sayangnya int penuh dengan kebingungan C/C++/Java), tetapi saya pribadi berpikir bahwa contoh kedua segera lebih mudah dibaca.

Saya juga berpikir kata kunci visibilitas crate akan membingungkan orang yang datang ke Rust dari bahasa lain. Jika bahkan banyak dari kita yang cukup terlibat dalam Rust untuk mengomentari utas ini terkejut, saya harus membayangkan itu akan menjebak orang-orang yang baru mengenal Rust juga.

Sintaks pub(crate) yang sedikit lebih panjang mungkin bukan masalah besar jika tidak menjadi peringatan/kesalahan untuk memiliki item pub yang tidak dapat dijangkau di luar peti. Saya pribadi berharap jika saya memiliki pub(crate) struct Foo { ... } , bahwa kompiler dapat menyadari bahwa semua pub fn s dalam impl Foo jelas tidak dapat dijangkau, dan tidak mengganggu saya tentang hal itu.

Saya merasa itu hanya pekerjaan sibuk saat ini di Rust 2015 jika saya pernah menandai jenis dari pub struct Foo ke pub(crate) struct Foo , bagaimana kompiler kemudian berteriak di semua tempat yang pub fn lainnya pub(crate) tiba-tiba, ketika masalahnya tidak nyata, karena tipe lainnya juga pub(crate) .

Saya juga menemukan ide @matklad untuk menggunakan kembali pub sebagai crate-public dan menggunakan export atau sesuatu untuk ekspor yang terlihat di dunia. Tapi itu mungkin perbedaan yang terlalu besar untuk sebuah edisi?

Menggunakan kembali pub sebagai crate-public dan menambahkan visibilitas baru untuk dunia-publik adalah proposal sebelum versi saat ini. Perubahan seperti itu pada semantik yang ada dianggap terlalu drastis bahkan untuk sebuah edisi, itulah sebabnya pub sekarang mempertahankan artinya saat ini.

Apa yang kurang dibahas dan dipertimbangkan, menurut saya, adalah penggunaan kembali pub hanya melalui lint. Mungkin kita dapat mengganti lint dari "peringatkan pub yang tidak dapat diakses di luar peti" menjadi "peringatkan pub yang dapat diakses di luar peti", dan tambahkan pub(extern) yang murni opsional pub(extern) / export kata kunci. Artinya, jangan ubah semantik apa pun, cukup tambahkan sintaks pembungkaman serat.

Saya menduga ini akan kurang mengganggu, berdasarkan asumsi bahwa ada lebih sedikit barang publik dunia daripada barang publik peti. Itu juga akan mempertahankan makna intuitif (meskipun agak salah) dari pub sebagai "ekspor dari modul saat ini" daripada menghadapkan semua orang dengan perilaku visibilitas yang sebenarnya.

Rust menyukai singkatannya yang sangat pendek, dan int sayangnya penuh dengan kebingungan C/C++/Java

FWIW, meskipun hanya menyimpan dua karakter, jika kita ingin menyingkat internal , singkatan "benar" mungkin, dengan analogi dengan extern al, menjadi intern . Sayangnya itu juga merupakan kata benda dengan arti yang berbeda dan dipahami secara umum. Baiklah.

@glaebhoerl intern adalah pilihan yang baik untuk dipertimbangkan! ❤️

Simetri dengan extern sangat bagus, dan IMO akan sangat mengurangi potensi kebingungan dengan bentuk kata benda intern .

Ini pendek, (hanya 1 karakter lebih dari crate ) dan tidak berbenturan dengan use crate:: .

Contoh yang diperbarui akan terlihat seperti:

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

intern mod color;

...

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

Saya telah menyebutkannya sebelumnya, tetapi saya tidak yakin apa masalahnya dengan kata benda yang digunakan sebagai kata sifat?

Untuk rekap: ada banyak kata benda yang dapat digunakan sebagai kata sifat, misalnya. kucing rumahan, mouse komputer, meja komputer, dll... Pencarian google untuk _kata benda bahasa Inggris yang digunakan sebagai kata sifat_ tampaknya menunjukkan bahwa pada dasarnya tidak ada yang salah meskipun tidak semua kata benda berfungsi sebagai kata sifat.

Mari kita coba:

_crate mod hello;_ Sebuah modul crate bernama hello, terasa baik-baik saja.
_crate fn world() {}_ Fungsi peti bernama world, terasa baik-baik saja.
_crate struct Foo;_ Sebuah struct peti bernama Foo, terasa baik-baik saja.
_crate enum Bar {}_ Crate enum bernama Bar, terasa baik-baik saja.
_crate trait Baz {}_ Crate trait bernama Baz, terasa baik-baik saja.

_crate use self::local::Foo;_ Ack, yang ini tidak berfungsi, penggunaan peti? Anda dapat membacanya sebagai peti item yang dapat digunakan bernama Foo. Itu merusak pola.

Ini juga bisa menjadi canggung ketika digunakan di depan anggota struct dan bahkan lebih dalam kombinasi dengan peti sebagai akar jalan.

Sementara peti tidak sempurna, saya tidak yakin bahwa 'menjadi kata benda' adalah faktor penentu.

Masalahnya adalah hal itu sangat jarang terjadi. Tidak ada bahasa pemrograman yang saya tahu yang menggunakan kata benda sebagai pengubah tipe.

@Centril

menjadi masalah; kemudian IDE/editor yang memahami sintaks Rust dapat menyorot token peti di posisi berbeda dengan warna berbeda. Itu harus menjernihkan perbedaan dengan baik, saya pikir.

Secara pribadi, sementara saya menemukan fitur editor yang berbeda bagus, saya tidak berpikir kita harus merancang bahasa dengan asumsi editor yang cukup maju. Saya merasa seperti C# dirancang dengan cara ini dan itu adalah faktor utama dalam frustrasi saya dengan bahasa itu.

@epage Saya pikir crate sebagai pengubah visibilitas adalah ide yang bagus terlepas dari penyorotan; Saya hanya menyarankan bahwa penyorotan adalah mitigasi tambahan . Secara khusus, seharusnya cukup sepele bagi editor mana pun untuk menyorot crate:: berbeda dari crate field karena yang pertama selalu crate + :: yang mudah diperiksa untuk semua kasus kecuali crate ::foo::bar (tapi ini akan cukup jarang..).

Sebagai orang IDE, saya pikir penyorotan seperti itu akan menambah jumlah kebisingan yang signifikan untuk jumlah informasi yang sangat sedikit, menjaring negatif. IMO (ini sangat pribadi, tetapi diinformasikan dengan menggunakan dan mengimplementasikan IDE yang kuat) penyorotan berfungsi paling baik ketika menyampaikan informasi non-lokal semantik (apakah penggunaan ini merujuk ke variabel yang dideklarasikan dengan mut ) dan de menekankan aspek kode "boilerplaty" lokal (jadi semua kata kunci harus ditata persis sama).

Bagi saya dom (yaitu: domestik) adalah kandidat potensial.

Ini memiliki tiga huruf (bagus untuk penyelarasan, mudah diingat), itu bukan kata benda, dan - selain 'Model Objek Dokumen' - Saya tidak berpikir itu memiliki ambiguitas tertentu yang melekat padanya.

pub struct MyStruct {
    dom num: i32,
    pub msg: String,
}

Apakah ada yang punya pemikiran tentang ini?

Satu sudut tentang ini yang saya lihat disebutkan tetapi tidak dapat ditemukan dalam ringkasan (terima kasih telah melakukannya btw!) adalah bagaimana pintasan cocok dengan sintaks pub() yang ada.

Jika pub dan <something> (misalnya crate ) memiliki arti khusus, itu akan mengurangi visibilitas, dan dengan ekstensi keakraban, dari pub(<something>) . Solusi apa pun yang kami gunakan, saya pikir itu harus mendukung atau mengganti mesin yang ada daripada menjadi yang lain.

Misalnya, jika kita menggunakan crate atau pengganti:

  • Haruskah crate diperpanjang untuk mengambil pembatasan pelingkupan (misalnya crate(<something>) )?
  • Haruskah kita mencela pub() jadi pub hanya memiliki satu arti?

Mempertimbangkan ini dan pemahaman saya tentang tujuannya (mengklarifikasi API publik dari API internal), membuat saya membuat ulang ide @vitiral tentang pub(extern) .

  • Cocok dengan mesin yang ada
  • imo meningkatkan mesin yang ada dengan membuat pub jalan pintas dari pub(<something>) daripada menjadi kasus khusus
  • Jika API publik secara signifikan lebih kecil daripada API pribadi, maka kami telah menimbang sintaks dengan cara yang benar.
  • Tetapi mungkin membingungkan orang yang berasal dari bahasa lain di mana public artinya mungkin ada di API publik Anda.

Dampak RE pada enkapsulasi

Salah satu manfaat dari sistem pub yang ada adalah enkapsulasi. Cara mudahnya adalah mengekspos API hanya satu tingkat ke atas. Ini membuatnya lebih mudah untuk membuat hal-hal bersifat publik ke bagian-bagian peti tetapi pribadi untuk keseluruhan ciptaan.

Meskipun masih akan ada pub(super) , memiliki pintasan untuk pub(crate) akan mendorong orang untuk lebih menggunakannya, mendorong orang untuk tidak merangkum API mereka.

Saya menduga ini bukan masalah karena budaya peti kecil.

Tetapi dalam mempertimbangkan ini, ini memberi saya iterasi lain pada komentar saya di atas pada pub(extern)

  • pub harus menjadi jalan pintas untuk pub(super)
  • pub(extern) diperlukan untuk API publik Anda.

Saya sebelumnya mengemukakan kekhawatiran orang-orang yang beralih dari bahasa lain. Ini lebih cocok dengan mereka.

  • Lebih cocok dengan cara kerja public dalam berbagai bahasa
  • Beberapa bahasa cenderung memiliki mekanisme berbeda untuk API publik, jadi ini dapat dijelaskan kepada mereka.

imo ini adalah yang terbaik dari semua dunia. Jadi pisahkan dan bantu saya memahami mengapa tidak :)

Saya masih membenci sintaks pub(foo) . Secara hiperbolis, sepertinya tidak dapat memutuskan apakah itu panggilan fungsi atau gabungan beberapa kata kunci. Kami tidak menggunakan let(mut) atau for(in) jadi apa masalahnya dengan yang satu ini?

@parasyte pub<foo> untuk menang! Lagi pula, bukankah ini _jenis visibilitas_?

pub<crate> atau pub(crate) benar-benar merasa lebih baik.

Beberapa pemikiran dari seseorang yang pindah kamp:

Awalnya saya sangat menentang crate dan berpikir "ini merusak pub yang bagus".

Saya kemudian mencobanya secara berdampingan di beberapa proyek saya dan membiarkannya meresap.

Terus terang, setelah beberapa hari saya tidak tahan melihat pub(X) lagi, rasanya kikuk dibandingkan, dan lebih sulit untuk dibaca.

Awalnya saya khawatir akan ada ambiguitas (visual); tetapi bagi saya yang terjadi sebaliknya: Jika saya melihat crate sekarang saya tahu itu, yah, "barang peti". Baik itu mengimpor modul atau mendeklarasikan visibilitas. Apa sebenarnya yang ada di sebagian besar kasus sangat jelas dari konteksnya (seperti ambiguitas dalam bahasa Inggris).

Saya dapat melihat mungkin masih ada sisa ambiguitas "lebih keras" (visual) dalam beberapa kasus, tetapi saya tidak ingin menukarnya kembali dengan apa yang sekarang terasa seperti kemenangan keterbacaan kuantitatif besar-besaran (seperti dalam: "baris kode sumber yang memerlukan lebih sedikit tokenisasi/usaha visual vs. baris kode sumber yang menjadi lebih ambigu" ).

Dari sudut itu crate - intern (atau asimetri lainnya) juga akan terasa seperti langkah mundur.

Setelah mengatakan ini, saya tidak tahu tentang ambiguitas parsing. Jika saya harus memilih satu, saya lebih suka memiliki cerita bagus tentang " crate berarti barang-barang peti" daripada cerita bagus tentang " crate ::foo::bar hanya berfungsi".

Dua sen saya adalah bahwa:

  • Saya telah menggunakan crate mod , crate struct , crate fn , ... secara ekstensif dan saya merasa sangat berguna.
  • Saya tidak terlalu peduli bagaimana namanya ( crate , pub(crate) , ...) asalkan tidak terlalu panjang karena saya sering menggunakannya.

Jika terserah saya, saya akan menggunakan vis sebagai kata kunci, dan jenis visibilitas sebagai pengubah, misalnya vis(pub) , vis(crate) , dll karena ini membuat lebih banyak akal bagi saya.

Mengingat bahwa kita sudah terjebak dengan pub sebagai "penentu visibilitas", saya sebenarnya suka crate . pub(crate) membaca untuk saya sebagai publik untuk modul ini, pribadi untuk peti - saya menemukan menggunakan publik dan pribadi pada saat yang sama di sini aneh.

Memperkenalkan kata kunci baru dan kata kunci kontekstual, dll. menurut saya tidak sepadan. Mengajarkan bahwa ada dua visibilitas mengubah pub dan crate , dan yang satu berarti publik, dan yang lainnya berarti pribadi untuk peti, agak masuk akal bagi saya, tapi mungkin saya baru saja terbiasa crate sudah selama dua minggu terakhir.

Bagi mereka yang menyarankan kata kunci yang sudah digunakan (yaitu: crate ) menggabungkan makna, saya berpendapat bahwa konteks lebih penting daripada kata itu sendiri. Otak mem-parsing semuanya dengan konteks (bagaimana kompiler mem-parsing ini adalah masalah yang berbeda): ini menjelaskan mengapa kami tidak menggabungkan makna semantik for dalam for x in y dan impl X for Y .

Demikian pula, memperkenalkan crate sebagai qualifier visibilitas kemungkinan tidak akan menimbulkan kebingungan karena artinya, dalam konteks qualifier anggota atau fungsi, jelas ketika diberikan dengan konteks tambahan tersebut. Misalnya, crate fn my_func(); tidak terbaca sebagai "ini adalah peti", tetapi terbaca sebagai "ini adalah fungsi peti yang terlihat".

Yang mengatakan, fakta bahwa itu adalah kata benda tidak konsisten. Saya akan membuat kata kunci penentu visibilitas baru untuk mengatasi masalah ini.

Sebenarnya, jika ada sesuatu yang pasti akan membingungkan pengguna, itu adalah sintaks pub(crate) yang secara intuitif terlihat seperti pemanggilan fungsi dan tidak memiliki padanan sintaksis lain di tempat lain dalam bahasa tersebut. Bagi saya, itu terasa seperti peretasan yang buruk.

Sebagai seseorang yang mengemukakan kekhawatiran tentang penggunaan crate sebagai pengganti pub(crate) dan setelah membaca posting terbaru @aturon :

Mendukung peti sebagai pengubah visibilitas (dilacak di sini 138. Mengingat umpan balik sejauh ini, fitur ini tidak mungkin distabilkan untuk Rust 2018 .

Saya hanya ingin memastikan bahwa saya jelas bahwa saya secara pribadi sepenuhnya mendukung penggantian pub(crate) dengan sesuatu (seperti yang saya pikir mayoritas).

Dalam urutan preferensi, dengan apa yang saya rasa akan paling mudah dipahami, terutama bagi mereka yang baru atau tidak terbiasa dengan Rust:

  1. intern (atau kata kunci baru serupa lainnya)
  2. crate
  3. pub(crate)

Jika tim inti merasa intern atau sesuatu yang serupa pada akhirnya tidak akan pernah diterima, maka saya akan tertinggal crate karena saya masih berpikir ini adalah peningkatan besar dari pub(crate) , untuk alasan @Centril dan yang lainnya telah diartikulasikan.

Jadi saya tidak akan menghalangi hal ini jika tim inti yang jauh lebih berpengalaman merasa ini adalah jalan terbaik ke depan. Ini rapi untuk hanya dapat memberikan umpan balik mengungkapkan ide-ide untuk dipertimbangkan. 👍 karat!

@ralfbiedert

Awalnya saya khawatir akan ada ambiguitas (visual); tetapi bagi saya yang terjadi sebaliknya: Jika saya melihat peti sekarang, saya tahu itu, yah, "barang peti". Baik itu mengimpor modul atau mendeklarasikan visibilitas. Apa sebenarnya yang ada di sebagian besar kasus sangat jelas dari konteksnya (seperti ambiguitas dalam bahasa Inggris).

@zesterer

Bagi mereka yang menyarankan kata kunci yang sudah digunakan (yaitu: peti) menggabungkan makna, saya berpendapat bahwa konteks lebih penting daripada kata itu sendiri. Otak mem-parsing semuanya dengan konteks (bagaimana kompiler mem-parsing ini adalah masalah yang berbeda): ini menjelaskan mengapa kami tidak menggabungkan makna semantik for in untuk x di y dan impl X untuk Y.

Saya tidak bermaksud untuk memanggil kalian berdua secara pribadi tetapi menjadi contoh orang-orang yang mendukung perubahan setelah menggunakannya.

Sementara saya merasa aneh, perhatian terbesar saya adalah dengan non-rustacea.

  • Bagaimana hal ini dapat memengaruhi pendapat seseorang dalam menilai karat? Satu hal kekhasan sintaks seharusnya tidak cukup untuk menghalangi mereka, tetapi jika Anda menumpuknya dengan masa hidup dan hal "aneh" lainnya, itu mungkin membuat orang putus asa
  • Bagaimana hal ini memengaruhi orang yang mempelajari Rust?
  • Bagaimana pengaruhnya terhadap orang yang tidak mengenal Rust tetapi perlu memodifikasinya?

Saya akan senang jika kita dapat melakukan studi kegunaan tentang ini untuk mengetahui lebih baik seberapa besar dampak masalah ini.

@epage , sangat setuju, bagian Rust yang menghadap pengguna harus diuji UX. Namun, saya pikir inilah yang terjadi saat ini, dan kami sedang mendiskusikan hasilnya.

Sebagai tambahan, beberapa pengamatan anekdotal dari perusahaan kami:

Saya adalah "pendukung Karat" di departemen kami, bekerja dengan 3 orang lainnya. Semua memiliki latar belakang yang solid di C#, tetapi relatif baru di Rust. Suatu hari saya memigrasikan proyek penelitian kami ke Rust 2018, bersama dengan " crate -stuff".

Ketika kami membaca kodenya, percakapannya kira-kira seperti ini:

"Jadi ini beberapa perubahan lain yang saya buat; sistem impor baru; pengubah."

"Itu buat apa?" (menunjuk use crate::object dan crate x: object )

"Impor dari peti ini." dan "Pengubah visibilitas".

"Ah, oke. Ada lagi yang berubah?"

Akhir dari diskusi.

Tentunya, kami mengobrol lebih banyak tentang fitur baru, dan apakah kami harus mengadopsi pola tertentu; tetapi "aspek pengajaran" dari kedua item ini diringkas menjadi beberapa kata dan belum disebutkan sejak itu (sepengetahuan saya).

Jika saya mendengar hal lain saat kita berbicara berikutnya, saya akan memperbarui komentar ini.

@ralfbiedert Terima kasih telah berbagi!

@epage , sangat setuju, bagian Rust yang menghadap pengguna harus diuji UX. Namun, saya pikir inilah yang terjadi saat ini, dan kami sedang mendiskusikan hasilnya.

Sementara saya menghargai anekdot UX ini, terutama untuk sisi kemampuan belajar, saya tidak berpikir saya akan memenuhi syarat proses masalah ini sebagai pengujian UX. Komentar saya mengacu pada proses yang lebih formal yang dapat membantu mendapatkan pemahaman yang lebih dalam, menghilangkan bias, dll.

Berikut adalah beberapa pemikiran yang datang dari seorang pemula Rust. Pertama, saya ingin mengatakan bahwa sesuatu yang benar-benar terasa waras dan menyenangkan dengan bahasa ini adalah pendekatan "tidak dapat diubah secara default, pribadi secara default".

Sekarang, pub bagus karena sederhana dan diharapkan dalam bahasa modern. Saya merasa bahwa harus tidak mempelajari ini dalam konteks Rust dan menaburkan kata kunci lain di mana-mana agak canggung. Secara semantik, rasanya tepat untuk mengartikan "ini adalah tombol yang muncul di kotak", kotak itu adalah modul: visibilitas "dari satu tingkat ke atas".

Jadi, bagi saya, menggunakan crate atau kata kunci lain seperti itu alih-alih pub hanya terasa gatal: jika menjadi publik adalah non-default, diekspor keluar dari peti seharusnya lebih istimewa . Artinya, API peti harus dilambangkan dengan cara khusus.

Jadi, saya sepenuh hati setuju dengan @epage , pub harus tetap sama dan pub(extern) dari beberapa jenis diperkenalkan. Kata kunci yang dikurung benar-benar terasa berbulu, jadi mungkin itu layak mendapatkan kata kunci khusus. crate kata kunci akan berfungsi dalam arti itu, saya dapat melihatnya berarti "ini anggota peti yang diekspor". Atau export sebenarnya, saya tidak tahu. Mungkin semua poin saya adalah bikeshed, dan ini semua berarti "kata kuncinya tidak benar". Tetapi pub sangat umum sehingga tidak terasa istimewa, jadi seharusnya tidak mewakili sesuatu yang benar-benar istimewa (API yang diekspor peti).

Saya menonton ceramah di RustConf akhir pekan ini yang menggunakan banyak pub(crate) dalam contoh kodenya, dan itu benar-benar membuat saya menginginkan crate yang lama. Saya masih sangat pro rencana awal.

@steveklabnik

Saya menonton ceramah di RustConf akhir pekan ini yang menggunakan banyak pub(crate) dalam sampel kodenya, dan itu benar-benar membuat saya menginginkan peti tua biasa. Saya masih sangat pro rencana awal.

Apakah konteks komentar ini sebagian besar dari RustConf atau apakah itu memperhitungkan utas ini dan mengandaikan ketidaksepakatan dengannya? Sebelumnya, saya memberikan solusi alternatif, bukan untuk pub(crate) tetapi untuk persyaratan yang mendorong salah satu dari pub perubahan dan saya berharap itu akan memenuhi kebutuhan orang.

Melihat

@superseed

Jadi, saya sepenuh hati setuju dengan @epage , pub harus tetap sama dan pub(extern) dari beberapa jenis diperkenalkan. Kata kunci yang dikurung benar-benar terasa berbulu, jadi mungkin itu layak mendapatkan kata kunci khusus. kata kunci peti akan berfungsi dalam pengertian itu, saya dapat melihatnya berarti "ini anggota peti yang diekspor". Atau ekspor sebenarnya, saya tidak tahu. Mungkin semua poin saya adalah bikeshed, dan ini semua berarti "kata kuncinya tidak benar". Tetapi pub sangat umum sehingga tidak terasa istimewa, jadi seharusnya tidak mewakili sesuatu yang benar-benar istimewa (API yang diekspor peti).

RE "Kata kunci yang dikurung benar-benar terasa berbulu"

Sementara secara pribadi saya pikir mereka rapi ketika saya mengetahui tentang mereka (jauh lebih baik daripada semua-atau-tidak sama sekali friend ), kekhawatiran saya yang lebih besar adalah kami tidak membuat sintaks paralel tetapi merangkul apa yang kami miliki atau temukan solusi alternatif.

Di samping itu...

RE Atau export sebenarnya,

Saya tidak berpikir menambahkan export bertentangan dengan komentar saya sebelumnya berbeda dengan crate . Dalam konteks ini, export dapat diperlakukan berbeda dari visibilitas. export akan menyiratkan pub(crate) . Saya menduga ini tidak akan memiliki banyak masalah dalam mengajar.

Saya dapat melanjutkan dengan cara apa pun untuk perluasan ide asli saya ini.

@superseed

pub […] visibilitas "dari satu tingkat ke atas".
crate kata kunci akan berfungsi dalam arti itu, saya dapat melihatnya berarti "ini anggota peti yang diekspor".

Saya pikir pemahaman Anda tentang arti kedua kata kunci ini mungkin kebalikan dari apa yang diusulkan di sini, yaitu pub berarti publik untuk semua orang sementara crate berarti dapat diakses dari peti yang sama.

@epage

Dalam kasus pub(crate) , itu memang menawarkan fitur yang sangat rapi, dan benar-benar terbaca dengan baik, tetapi terlihat terlalu mirip dengan panggilan fungsi di mata saya. yaitu tanpa penyorotan sintaksis, saya mungkin akan sangat bingung, dan penyorotan seharusnya tidak diperlukan untuk memahami semantik suatu bahasa.

@SimonSapin

Memang, dan saya menyadari itulah cara yang seharusnya dipahami, tetapi crate -- menjadi kata benda -- terasa seperti mendeklarasikan baik peti (?) atau properti peti. Penekanan menyatakan dan tidak memenuhi syarat.

Dan public / pub adalah kualifikasi yang ada di mana-mana, tidak terasa (bagi saya!) seperti itu seharusnya berarti "ini diekspor keluar dari peti". Ini memiliki arti "ini terlihat dari luar konteks apa saya berada", seperti halnya penggunaannya dalam visibilitas anggota struct yang memenuhi syarat (dan perbaiki saya jika saya salah tetapi saya tidak' t berpikir semantik berubah dalam kasus itu).

Dan publik/pub adalah kualifikasi yang ada di mana-mana, tidak terasa (bagi saya!) seperti itu seharusnya berarti "ini diekspor keluar dari peti". Ini memiliki arti "ini terlihat dari luar konteks saya", seperti halnya penggunaannya dalam visibilitas anggota struct yang memenuhi syarat (dan perbaiki saya jika saya salah tetapi saya tidak berpikir semantiknya adalah berubah dalam kasus itu).

pub selalu berarti "ini diekspor keluar dari peti"- ini bukan perubahan, sudah begitu. Fakta bahwa begitu banyak yang berasumsi sebaliknya adalah mengapa tingkat visibilitas pub(crate) didorong sama sekali.

pub selalu berarti "ini diekspor dari peti"

Saya pikir pemahaman ini juga dapat menyebabkan beberapa kebingungan, karena itu bukan gambaran lengkapnya. pub benar-benar berarti "Saya tidak peduli siapa di luar modul ini yang mengakses item/bidang/metode ini". Untuk diekspor dari peti, masih memerlukan jalur ke item yang juga memiliki pengubah pub yang sama.

Detail ini cukup biasa dalam banyak bahasa. Itu juga mengapa saya tidak tertarik pada serat unreachable_pub , karena itu adalah bagian dari apa yang mendorong masalah ini begitu banyak. Jika saya memiliki tipe yang tidak pernah diekspor di tingkat atas, maka mengganggu saya bahwa saya menandai metode itu pub hanya terasa seperti kebisingan.

@rpjohnst Apakah itu benar-benar yang selalu dimaksudkan? Bukankah rantai "terlihat dari super " dari atas peti yang membuat elemen diekspor, dan tidak memenuhi syarat elemen daun itu sendiri sebagai pub ?

Tidak, itu bukan keseluruhan cerita, dan klarifikasi @seanmonstar mengisyaratkan sisanya. Pengecualian terbesar adalah mengekspor ulang- Anda dapat pub use sesuatu yang modul induknya bersifat pribadi. Contoh yang lebih aneh adalah sesuatu seperti ini , di mana Anda diizinkan untuk menggunakan item pub di antarmuka publik meskipun modul induknya bersifat pribadi.

Dan menuju ke arah lain, pub(crate) dan visibilitas yang lebih rendah tidak dapat dilewati dengan cara yang sama- Anda tidak dapat pub use sesuatu yang belum pub , bahkan jika pub use itu sendiri tidak terlihat dari luar peti.

Jadi visibilitas item itu sendiri tidak secara langsung tentang visibilitasnya ke super , tetapi "batas atas" visibilitasnya di mana saja .

Oooh oke, terima kasih atas penjelasannya! Saya memiliki model yang jauh lebih naif dalam pikiran. Lebih masuk akal mengenai komentar sebelumnya tentang "arti pub saat ini".

Kami membahas secara singkat hari ini dalam pertemuan @rust-lang/lang:

  • Banyak dari kita merasa positif tentang hal ini tetapi masih ada keraguan tentang pilihan kata kunci, dan apakah kata kunci tersebut dapat menimbulkan kebingungan jika digabungkan dengan jalur crate::foo::bar
  • Namun, perlu ditunjukkan bahwa kita harus memutuskan cara seperti apa untuk menyelesaikan struct Foo ( crate :: foo :: Bar ) -- apakah ini bidang pribadi bertipe (crate::foo::Bar) atau bidang crate jenis ::foo::Bar ?

    • Sejujurnya saya tidak yakin apa yang kami uraikan seperti hari ini

Jawaban: kami mengurainya sebagai jalan ( playground ).

Ini sepertinya.. mungkin tidak masalah bagi saya, karena saya pikir jalur ::foo::bar akan menjadi semakin langka.

Banyak dari kita merasa positif tentang hal ini, tetapi masih ada keraguan tentang pilihan kata kunci, dan apakah kata kunci tersebut dapat menimbulkan kebingungan jika digabungkan dengan jalur crate::foo::bar

@nikomatsakis apakah ada catatan pertemuan atau ringkasan untuk kita ikuti? Di dalam utas ini, saya tidak pernah melihat diskusi tentang setidaknya satu dari kekhawatiran saya[0] atau banyak diskusi tentang proposal tandingan. Mungkin [0] dan beberapa lainnya dibahas di berbagai utas internal tetapi itu banyak yang harus digali.

[0] membuat sintaks visibilitas paralel mendorong pub(...) ke dalam ketidakjelasan dengan perasaan kita harus menghapus atau merangkul pub(...)

@epage

@nikomatsakis apakah ada catatan pertemuan atau ringkasan untuk kita ikuti?

tidak maaf; Kami tidak membahasnya untuk waktu yang lama (paling lama beberapa menit) dan tidak menuliskan catatan rapat tentang hal itu.

@eddyb secara singkat menyinggung my sebagai pengubah visibilitas yang lebih pendek dan lebih ergonomis.

Saya pikir saya mengatakan mine tetapi my bahkan lebih pendek, indah!
(Sebagai catatan, saya setengah bercanda dalam pertemuan itu)

EDIT : jika my adalah crate-local, dapatkah kita mengganti pub dengan our ? misalnya:

our struct Foo(my FooImpl);

(Sebagai catatan, saya setengah bercanda dalam pertemuan itu)
jika my adalah crate-local, dapatkah kita mengganti pub dengan our ?

Perl: membuat lelucon menjadi kenyataan.
https://perldoc.perl.org/functions/my.html
https://perldoc.perl.org/functions/our.html

my bagus (dan telah muncul sebelumnya), masalahnya tidak lebih jelas dari local , internal , atau apa pun, sehubungan dengan apa (atau dalam kasusnya, yang ), yang merupakan seluruh masalah.

Situasi canggung yang kami hadapi adalah kami ingin memiliki tiga tingkat privasi -- "sepenuhnya publik", "sepenuhnya pribadi", dan "suatu tempat di antara" (yaitu, tingkat peti) -- dan karena kendala kompatibilitas mundur, kami 'terjebak dengan yang pertama adalah pub , yang kedua adalah default implisit, dan harus membuat sesuatu yang baru untuk yang ketiga. Dan bahasa Inggris tidak memiliki banyak kata yang menunjukkan "tidak sepenuhnya global, atau sepenuhnya lokal, tetapi di suatu tempat di antara" dengan tepat.

Dan kata kunci crate adalah kata kunci yang memenuhi hal ini, karena dikatakan tepat di namanya apa cakupan sebenarnya -- itu peti. Tapi (sebelum Anda keluar dari "Saya tahu itu!"), harga ini adalah bahwa itu tidak lagi jelas bahwa itu adalah pengubah visibilitas . "Pub" adalah kependekan dari "publik", yang bisa diintuisi. Tetapi tidak ada bahasa lain yang memiliki konsep "peti" (dengan nama itu); untuk memiliki harapan untuk memahami crate struct , pertama-tama kita harus belajar tentang ini. 1 Ini mengharuskan kita untuk melakukan penarikan lebih lanjut dari "anggaran keanehan bahasa", dan pendapat mungkin berbeda tentang apakah saldo masih positif.

Sementara itu pub(crate) menyelesaikan kedua masalah -- ini memberitahu Anda bahwa itu adalah pengubah visibilitas, dan itu memberi tahu Anda apa cakupannya -- tetapi sebagai gantinya itu panjang dan canggung.

Jadi itu pada dasarnya bentuk kesulitannya.

1 (Seseorang di atas menggambarkan interaksi yang berlangsung, "mereka bertanya apa arti crate , saya memberi tahu mereka bahwa itu adalah pengubah visibilitas, dan itulah akhirnya". Situasi yang bermasalah, dan mungkin lebih umum, adalah ketika Anda tidak memiliki Rustacean duduk di sebelah Anda.)

FWIW, saya akan baik-baik saja dengan our atau my untuk item lokal peti.
our bahkan merupakan kata kunci tiga huruf dan cocok dengan pub ~dan dengan Perl~.
Apakah masalahnya terdengar terlalu informal (untuk penutur asli bahasa Inggris?)?

Bagaimana perasaan orang tentang intern ? Ini satu karakter lebih panjang dari crate , tetapi selain itu saya pikir itu akan lebih intuitif daripada crate untuk orang yang baru mengenal Rust dan memiliki beberapa simetri yang bagus untuk kata kunci extern .

IMO our dan my memiliki kelemahan yang sama dengan local dan internal : mereka tidak begitu jelas tentang ruang lingkupnya. local khususnya cukup membingungkan, karena ruang lingkup akan sangat berbeda dari variabel lokal di mana lokal berarti pribadi ke ruang lingkup terlampir, yang untuk item akan menjadi modul, bukan peti. Saya menemukan internal agak tidak spesifik. Internal untuk apa? Modul? Tipe? peti? Mungkin jelas bagi mereka yang berasal dari bahasa yang menggunakannya tetapi belum tentu bagi orang lain. our dan my bahkan lebih kabur. Sebaliknya crate sangat jelas tentang ruang lingkup.

Mengenai pub(extern) , saya sebenarnya punya pertanyaan. Apakah masuk akal untuk memiliki extern "C" fn foo() {} , tanpa pub di depan? Karena jika tidak, kita dapat menggunakan kembali extern fn foo() {} untuk fungsi biasa, non "C" abi Rust juga. Saya berpikir bahwa kami dapat menyatukan itu dan tidak menyimpan sintaks eksternal khusus untuk FFI. Itu berarti extern sekarang diturunkan menjadi pub(extern) , pub tetap sama seperti hari ini tetapi menerima string ABI opsional saat item mendukungnya, dan lint untuk pub item diekspor tanpa pub(extern) atau extern .

extern fn foo() {
    println!("Just called a Rust function from Rust!");
}

#[no_mangle]
extern "C" fn foo_from_c() {
    println!("Just called a Rust function from C!");
}

Saya belum pernah melihat yang disebutkan di utas yang saya baca jadi maaf jika ini sudah pernah dibahas sebelumnya!

Apakah masuk akal untuk memiliki extern "C" fn foo() {} , tanpa pub di depan?

Ya- terkadang Anda hanya ingin menggunakan foo sebagai penunjuk fungsi, misalnya. Dan sebenarnya sintaks extern fn foo() {} tidak dapat digunakan kembali untuk ini karena extern tanpa "C" default ke C ABI, dan ini dianggap idiomatis setidaknya oleh beberapa orang.

Berikut adalah saran yang muncul sejak lama - mungkin kita dapat memberikan kesempatan lain sekarang karena beberapa aspek dari sistem modul baru telah dikristalisasi?

// Public to the world.
pub struct Foo;

// Private to the crate.
priv struct Foo;

// Basically not visible at all (only inside the module).
struct Foo;

Saya percaya ini masuk akal jika seseorang memikirkan:

  • "publik" sebagai "publik untuk dunia"
  • "pribadi" sebagai "pribadi untuk peti"
  • "tidak ada pengubah visibilitas" sebagai "pada dasarnya tidak terlihat sama sekali"

Beberapa orang memiliki reaksi spontan terhadap priv bukan yang paling membatasi, tetapi saya ingin membuat dua poin tentang itu:

  1. Di Rust, modul digunakan untuk mengatur hal-hal di bawah ruang nama, sementara peti digunakan untuk mendefinisikan antarmuka. Jadi jika peti adalah "unit API", maka masuk akal bagi pengubah visibilitas untuk berbicara tentang peti terutama.

  2. Saya pikir Java membuat kesalahan private yang berarti "pribadi untuk kelas" dan tidak ada pengubah visibilitas yang berarti "terlihat di dalam paket". Bagi saya, lebih masuk akal jika tidak ada pengubah (yaitu default) yang paling membatasi.

@stjepang Saya berpendapat bahwa dalam sebagian besar keadaan lain "pribadi" akan memiliki konotasi yang lebih ketat daripada keadaan yang tidak dimodifikasi. Spektrum privat-default-publik dalam pengertian umum analog dengan protected-available-advertised.

Klub pribadi lebih eksklusif daripada klub.
Tindakan pribadi menyiratkan bahwa beberapa upaya telah dilakukan untuk bersembunyi dari pandangan umum.
Pemikiran pribadi seharusnya menjadi konsep yang berlebihan mengingat kegagalan evolusi untuk memberi kita telepati, tetapi kebanyakan orang mengenalinya sebagai pemikiran yang dimaksudkan untuk tidak dibagikan.

Sebagai pelajar bahasa yang tidak berpengalaman, saya juga menyarankan bahwa kata kunci tambahan kurang dari beban kognitif daripada kata kunci tunggal dengan beberapa makna yang bergantung pada konteks. Lihat Costello, L and Abbot, B "Siapa yang pertama", 1938.

Saya merasa bahwa my dan our akan memiliki konotasi yang tidak kita inginkan, mengesampingkan kesulitan untuk menyimpannya sebagai kata kunci. Mereka membuat lelucon yang lucu, tetapi saya tidak berpikir kita harus pergi ke rute itu.

Sejujurnya saya merasa seperti orang akan belajar apa arti visibilitas crate . Saya pikir masalah yang lebih besar berasal dari kode yang menjadi sulit dibaca atau ambigu untuk diuraikan:

crate struct S(crate crate::Foo);

crate struct S(crate ::Foo);

Saya pribadi tidak melihat mereka sebagai showstoppers, tapi mereka benar-benar kekhawatiran yang sah di sini.

Ada paralel pub(path) dalam bahasa Scala, yaitu private[path] , yang bertindak hampir sama. Bunyinya sedikit berbeda, mengatakan "item ini pribadi, hanya mengizinkan orang dalam $path untuk melihatnya". Tetapi membuat sesuatu menjadi pribadi di Scala memerlukan anotasi, karena defaultnya adalah publik, yang tidak terjadi di Rust.

Terpikir oleh saya bahwa konsep C++ dari friend s juga mirip dengan pub(path) , sebagai titik preseden lainnya.

Pada akhirnya, masalahnya adalah:

  1. kata kunci crate digunakan untuk impor jalur relatif dan sebagai pengubah visibilitas,
  2. kata kunci crate mencegah sintaks pengubah visibilitas terpadu seperti pub(...) ,
  3. beberapa tidak menyukai sintaks pub(crate) (terlalu panjang, terlihat seperti pemanggilan fungsi).

Setelah 5 menit berpikir sangat dalam, saya menemukan yang berikut ini... :P

Sintaks Khusus untuk Pengubah Visibilitas

_(menggunakan @ sebagai contoh)_

<strong i="18">@pub</strong> use crate::Foo;

<strong i="19">@crate</strong> struct Bar;

Saya pribadi merasa itu sangat jelek dan saya tidak ingin mengetik @crate atau pub(crate) .

Kata Kunci Pengubah Visibilitas Berbeda

Karena sudah ada pub dan extern , saya pikir kata kunci crate sangat cocok (tidak mengejutkan ketika berasal dari bahasa dengan public , protected , private kata kunci).

crate struct Foo;

crate fn path() -> PathBuf { ... }

Tetapi seperti yang saya katakan, itu tidak bekerja dengan baik dengan awalan impor crate dan saya mulai merasa bahwa kita mengalami kemunduran. Saya merasa masalah sebenarnya terletak pada perubahan kejelasan jalur, misalnya, tanpa penyorotan sintaks:

use crate::utils;

sepertinya crate tidak memiliki arti khusus.

Dengan inspirasi besar dari sintaks makro deklaratif, alih-alih menemukan semacam sintaks terpadu untuk pengubah visibilitas, saya lebih suka memiliki yang berikut:

use std::io;
use std::path::Path;

use log::info;

use $crate::utils;

crate fn hello() -> io::Result<()> {
    utils::rm_rf(Path::new("/"))?;
    info!("Goodbye, World!");
}

( self , super dan crate jangkar khusus untuk jalur impor akan memerlukan awalan, misalnya, $crate , yang membuatnya cukup jelas bahwa mereka khusus dan terlihat seperti variabel)

Contoh berbelit-belit:

crate struct Foo(crate crate::Bar);

menjadi:

crate struct Foo(crate $crate::Bar);

Tampaknya ada masalah pelacakan duplikat: https://github.com/rust-lang/rust/issues/45388.
Menutup yang itu demi yang ini.

Apakah ada alasan implementasi rustc melakukan dogfood pada fitur ini? Setiap instance crate fn dapat diubah menjadi pub(crate) fn dan berhenti mengandalkan fitur AFAICT yang tidak stabil.

Saya tidak melihat alasan bagus mengapa kami melakukan itu. Baik Clippy dan rustc menggunakan fitur yang tidak stabil sepanjang waktu dan mereka harus melakukannya karena ini memungkinkan kami untuk mengujinya secara lebih ekstensif baik dalam hal menangkap bug dalam implementasi dan karena kami dapat merasakan bagaimana menggunakannya.

Dalam hal ini, penggunaan crate sebagai pengubah visibilitas di Clippy dan di rustc menurut saya menunjukkan bahwa itu membaca lebih baik daripada pub(crate) dan bahwa sebagian besar masalah yang dirujuk dalam masalah pelacakan ini bukan -masalah dalam praktek. Saya pikir https://github.com/rust-lang/rust/issues/53120#issuecomment -413466129, https://github.com/rust-lang/rust/issues/53120#issuecomment -414392549, dan https:/ /github.com/rust-lang/rust/issues/53120#issuecomment -413498376 juga menyarankan bahwa crate sebagai pengubah visibilitas juga berfungsi dengan baik di luar.

Karena ini bekerja dengan baik dalam praktiknya, karena banyak dari kita di tim bahasa merasa positif tentang hal itu , dan karena RFC diterima , saya pikir kita harus mempertimbangkan untuk menstabilkan crate sebagai pengubah visibilitas setelah mempertimbangkan bagaimana kita harus mengurai struct Foo ( crate :: foo :: Bar ) ( saat ini sebagai jalur, dan mungkin itu benar ).

FWIW, saya menggunakan fitur ini di cargo-n64 dan itu sangat bagus!

Saya menggunakan crate di rustc sepanjang waktu karena pendek dan tidak memiliki tanda kurung seperti pub(crate) .
Saya masih tidak suka cara membacanya.
Itu juga tidak memiliki 3 huruf, jadi pemformatan berubah bersama dengan pub <-> crate berubah.
Saya masih suka our secara tidak ironis.

@petrochenkov Pemahaman saya tentang apa yang Anda tulis adalah bahwa Anda lebih suka crate daripada pub(crate) tetapi juga menginginkan sesuatu yang lebih baik daripada crate . Apakah itu penilaian yang akurat?

FWIW, saya masih berpikir intern adalah pilihan yang baik.

  • Tidak ada tanda kurung
  • Lebih pendek dari pub(crate) (meskipun satu karakter lebih panjang dari crate )
  • Membaca lebih baik (IMO) daripada crate (yang digunakan untuk hal-hal lain seperti jalur, misalnya crate::foo::bar )
  • Memiliki simetri yang bagus dengan extern yang ada
  • Akrab, karena bahasa lain menggunakan sesuatu yang serupa ( internal ). Kotlin, C#, dll.

Karena itu, saya juga setuju bahwa pub(crate) harus diganti dengan something .

baik itu diselesaikan kemudian-- tiga huruf bagus, dan "magang" bagus, jadi... int . ;)

Bisakah kami meminta lint untuk kotak crate ::T (dengan spasi)?

@Centril Beberapa dari kami baru saja mendiskusikan jalan ke depan di #rocket. Berdasarkan komentar terbaru Anda, apakah ada kemungkinan FCP yang diusulkan dalam waktu dekat?

@jhpratt Saya sudah lama ingin menulis dan akhirnya mengusulkannya tetapi saya sibuk dengan hal-hal lain. Saya akan mencoba mencari waktu dalam waktu dekat.

Jadi, saya hanya menelusuri masalah, mencari sesuatu tentang makro, dan menemukan yang ini.

Sekarang kita sudah memiliki pub(crate) di stable untuk waktu yang lama, saya bertanya-tanya, bukankah masalah ini harus ditutup?

Menariknya, ini baru saja muncul pada pertemuan tim lang baru-baru ini, di mana membahas ini sebagai kemungkinan masalah yang ingin kami hidupkan kembali.

Berbicara secara pribadi, saya pasti rindu bisa menulis crate fn dan crate foo: T di bidang dan hal semacam itu. Ini bukan perbedaan sintaksis yang besar dari pub(crate) tetapi saya merasa itu membuat kode lebih mudah dibaca, terutama di struct yang memiliki banyak bidang publik. Saya juga merasa itu berkontribusi pada "model privasi" yang masuk akal dan disederhanakan --

  • struct, bidang bersifat lokal ke modul (alasan yang sangat sempit)
  • atau mereka digunakan di suatu tempat di dalam peti saat ini ( crate , harus ripgrep)
  • atau mereka publik untuk dunia ( pub )

Dalam pandangan saya, ada beberapa persimpangan antara kata kunci ini dan perubahan yang dibayangkan di https://github.com/rust-lang/rust/issues/48054 , dan saya lebih suka memastikan bahwa kita mengadopsinya bersama-sama. Saya lupa detailnya tetapi saya ingat bahwa ada kesalahan yang akan didapat seseorang ketika mencoba mempraktikkan model di atas.

Saya pikir langkah pertama menuju ini adalah seseorang untuk mencoba dan melakukan penulisan yang mendokumentasikan sejarah dan memastikan kami telah menyoroti semua masalah yang diangkat.

Satu perhatian khusus yang saya ingat adalah ambiguitas sintaksis dari

struct Foo(crate ::x)

Hari ini, ini diterima dan crate ::x mem-parsing sebagai jalur crate::x , tetapi masuk akal pengguna bermaksud crate untuk berfungsi sebagai pengubah visibilitas dengan ::x sebagai jalur .

Saya akan cenderung untuk memperkenalkan kembali pengubah crate dan untuk menjaga penguraian kasus di atas seperti sekarang ini. Sejak Rust 2018, jalur ::foo sebagian besar sudah tidak digunakan lagi -- jalur tersebut masih ada dan dapat berguna dalam konteks spesifik tertentu, seperti makro, tetapi sebagian besar istilah sekarang kami mendorong jalur absolut yang terlihat seperti crate_name::b , di mana crate_name dapat berupa kata kunci crate atau nama peti lainnya. Jadi kemungkinan besar crate::x (mengabaikan spasi) sebenarnya dimaksudkan sebagai jalur dan karenanya penguraian saat ini benar.

Jika kita ingin mengatasi potensi kebingungan pengguna, maka menurut saya lint yang peka terhadap spasi adalah ide yang cukup bagus. Dengan kata lain, struct Foo(crate ::x) akan memperingatkan, tetapi struct Foo(crate::x) tidak, meskipun keduanya diterima dan setara.

Secara pribadi, saya lebih suka sintaks terpadu dan lookahead(1) parser sederhana lebih banyak; Juga, peti adalah peti, dan ada peti.io di luar sana, dan semua itu tidak ada hubungannya dengan visibilitas _directly_ — hanya dalam konteks pub(_) .

Tapi yah, apa yang saya tahu? Ini hanya sudut pandang lain. Kalian tidak diragukan lagi memiliki lebih banyak pengalaman dan pendapat yang lebih berharga.

@nikomatsakis Ingin tahu apakah Anda memiliki pemikiran tentang intern untuk kasus penggunaan ini (atau memesan kata kunci baru di luar cakupan saat ini?).

Setelah beberapa tahun, perasaan saya masih sama: optimalkan untuk keterbacaan . Saya menemukan bahwa saya membaca kode lebih banyak daripada saya menulisnya . Jadi, pendapat saya adalah lebih jelas bagi saya untuk membaca pub(scope) , yang dapat berupa pub , pub(crate) , pub(super) , pub(in proto::h1) .


Namun, saya tidak berpikir kami benar-benar menambahkan sesuatu yang baru ke percakapan dengan pendapat ini, saya yakin kami telah mengatakan semuanya di komentar sebelumnya. Haruskah keputusan didasarkan pada sesuatu yang baru? Atau dengan kata lain, bagaimana kita memutuskan bahwa sekarang keputusan untuk mengadopsi sintaks ini harus ya ketika tidak atau ditunda beberapa tahun yang lalu?

Saya juga merasa itu berkontribusi pada "model privasi" yang masuk akal dan disederhanakan --

  • struct, bidang bersifat lokal ke modul (alasan yang sangat sempit)
  • atau mereka digunakan di suatu tempat di dalam peti saat ini ( crate , harus ripgrep)
  • atau mereka publik untuk dunia ( pub )

Saya gagal memahami manfaat dari penyederhanaan ini dan betapa berharganya kehilangan kekuatan ekspresif. Untuk apa nilainya, saya sering membuat item publik ke modul induknya (sehingga modul saudara dapat menggunakannya) tetapi tidak seluruh peti. Publik ke modul grand-parent kurang begitu, tapi masih sesekali.

Saya merasa bahwa penghentian pub(super) akan menjadi kerugian yang signifikan.


Secara terpisah, saya tidak senang menggunakan kata benda crate sebagai qualifier yang memodifikasi item yang dapat eksis secara independen. Sebagai perbandingan: pub(lic), unsafe, dan const(ant) adalah kata sifat. Kata benda yang sudah digunakan sebagai kata kunci dalam definisi item bukanlah kualifikasi tetapi menunjukkan sifat item tersebut: fungsi, sifat, modul, …

Peti sudah menjadi konsep yang kita tangani, tetapi dalam proposal ini definisi item yang dimulai dengan crate tidak mendefinisikan peti baru.

Sedikit info baru:

rust-analyzer menyediakan pelengkap dan bantuan untuk menambahkan pub(crate) , yang (secara subjektif) membuatnya jauh lebih tidak mengganggu untuk mengetik, dengan tiga penekanan tombol.

Saya setuju bahwa sedikit informasi baru yang ditambahkan di sini. Saya pikir langkah selanjutnya yang baik, jika kita ingin memperjuangkan proposal, adalah kembali, meringkas kekhawatiran yang beredar, dan membawanya ke depan tim untuk mencoba dan mencapai keputusan akhir. Saya tentu lebih memilih untuk menerima atau menolak proposal ini, saya lelah karena itu tergantung pada limbo.

Dari melihat keseluruhan masalah ini dengan cepat, saya pikir komentar terbaru @nikomatsakis merangkum semuanya dengan cukup baik. Selain beberapa orang terpilih yang masih mendukung hal-hal seperti intern , crate tampaknya menjadi yang paling logis (dan diterima di RFC 2126 ). Satu-satunya masalah yang benar-benar luar biasa adalah bagaimana mengurai fn foo(crate ::bar) .

Serat yang peka terhadap spasi putih yang diperingatkan secara default tampaknya merupakan tempat paling logis untuk memulai. crate ::bar saat ini diurai sebagai jalur, dan harus tetap demikian di Rust 2015 dan 2018. Saya akan membayangkan itu akan menjadi kandidat untuk perubahan besar dalam sebuah edisi.

Kasus crate ::bar sama sekali tidak penting dalam praktiknya dan sudah berperilaku secara konsisten dengan bahasa lainnya. Itu selalu menjadi topik pembicaraan, tolong jangan fokuskan perhatian padanya.

Saya tentu lebih memilih untuk menerima atau menolak proposal ini, saya lelah karena itu tergantung pada limbo.

Saya pikir saya akan memilih penolakan.
Saya telah secara konsisten menggunakan crate alih-alih pub(crate) di rustc dan meskipun lebih pendek sebagian besar masih terlihat tidak pada tempatnya, terutama pada bidang atau impor, dan memilih antara crate dan pub(crate) terasa seperti memilih di antara dua kejahatan sementara tidak yakin mana yang lebih rendah.

Ya. Yang lebih penting, adalah apa yang @SimonSapin sebutkan bahwa crate bar memang tidak mendefinisikan peti baru, meskipun berbunyi seperti jika ya.

@petrochenkov Anda tidak berpikir serat masuk akal? Secara pribadi, jika saya melihat crate ::bar tanpa melihat diskusi ini, saya mengharapkannya berperilaku seperti pub(crate) ::bar . Saya pikir mengizinkan spasi putih di jalur _at all_ membingungkan.

@jhpratt Akan sulit untuk menolak spasi putih di antara segmen jalur, karena sifat cara kerja parser dengan token. Juga akan merusak sejumlah besar alat seperti kutipan!, syn dan banyak lainnya.

Saya pikir saya akan mendukung penutupan ini juga. Saya telah melihat cukup banyak kebingungan yang diungkapkan tentang arti dari konstruksi ini sehingga saya tidak berpikir keuntungan singkatnya sebanding dengan potensi kerugian untuk keterbacaan.

Ini mungkin lebih cocok dengan masalah pelacakan "lebih besar" (tetapi tertutup) #44660, tetapi juga terkait langsung dengan pengubah visibilitas dan tidak cocok dengan sub-masalah lain #44660:

Pada titik tertentu saya ingat seseorang menyarankan bahwa pub(path) sekarang bisa menjadi legal, mengganti formulir pub(in path) dan memasukkan pub(crate) dan pub(super) . Itu tampaknya merupakan penyederhanaan yang bagus dari pub(...) , meskipun dalam arah yang berbeda dari crate , yang mungkin kita pertimbangkan juga.

Sunting: Sebenarnya tidak yakin ini berfungsi... struct S(pub(path) Type) ambigu (untuk penguraian LL-esque) dengan hal-hal seperti struct S(pub (Type,)) .

Jadi saya telah memberikan pemikiran ini selama beberapa bulan terakhir. Saya pikir saya sudah sampai pada posisi "tutup". Saya pikir ringkasan posisi saya adalah sebagai berikut:

  • Gagasan "tiga tingkat visibilitas" (modul, peti, dunia) relatif sederhana, yang menarik, tetapi tidak kehilangan kasus umum di dunia nyata. pub(super) , khususnya, saya temukan sangat umum dalam praktik, meskipun jarang membutuhkan lebih dari satu level (yaitu, pub(crate::foo) ). Misalnya, saya sering ingin memiliki modul yang memiliki sub-modul, dan menggunakan visibilitas peti untuk detail tersebut gagal mengomunikasikan tingkat privasi yang diinginkan.
  • Model "lokal ke beberapa bagian peti, atau publik ke dunia" juga secara konseptual sederhana dan elegan, dan mencakup semua kasus penggunaan tersebut.
  • pub(crate) fn , sementara secara signifikan kurang ringkas dari sekedar crate fn , tidak terlalu buruk. Sangat lucu bahwa pub(crate) meluas ke pub(crate::foo) , yang mencakup kasus penggunaan lain yang kadang-kadang saya dapatkan (yaitu, modul "besar" di dalam peti), tetapi itu sangat bertele-tele, saya curiga akan jarang jika pernah digunakan, dan kemungkinan besar modul besar itu akan lebih baik dimasukkan ke dalam subkrat ...
  • Saya pikir rintangan ergonomis terbesar di sekitar "tingkat privasi campuran" berasal dari serat dan kesalahan yang terkait dengan kami mencoba untuk memastikan bahwa (misalnya) semua jenis yang muncul di pub(x) fn adalah privasi yang sesuai. Kami telah mengubah aturan itu dan saya merasa seperti saya tidak lagi mengalami gangguan itu -- dan jika lebih banyak gangguan seperti itu muncul, saya pikir kami juga bisa mengatasinya.

    • Misalnya, mungkin untuk menulis pub pada bidang yang berarti "sebagai publik seperti struct itu sendiri", dan saya pikir itu berfungsi dengan baik.

Dan, tentu saja, fakta bahwa tidak menambahkan crate fn sekarang tidak berarti kita tidak dapat menambahkannya nanti. Secara khusus, saya pikir model "tiga tingkat privasi" akan bekerja lebih baik jika kita memiliki beberapa cara untuk melakukan "peti sebaris yang ringan" di dalam peti lain. yaitu, jika alih-alih memiliki submodul di dalam peti, saya dapat mendeklarasikan peti pribadi dengan semua yang menyiratkan (terutama, mungkin, hubungan seperti DAG dengan hal-hal lain). Saya tidak yakin apakah peti sebaris yang ringan akan benar-benar berfungsi, tetapi peti itu mungkin menutupi dan mengganti banyak kasus penggunaan seperti pub(super) . Jika pernah menjelajahi itu, maka saya akan mempertimbangkan untuk membuka kembali diskusi sekitar crate fn , karena mungkin menjadi jauh lebih berguna/umum.

Singkatnya, saya akan mendukung penghapusan tingkat visibilitas crate dari kompiler dan menghapus gerbang fitur.

Saya hanya ingin memeriksa kapan fitur ini mungkin distabilkan dan saya terkejut dan kecewa karena ada rencana untuk menghapusnya. Saya telah menggunakannya setiap hari sejak tidak lama setelah ditambahkan dan saya hampir tidak terganggu oleh salah satu masalah yang dibahas di atas. Saya masih belum menulis sesuatu yang menyerupai crate ::path , misalnya, dan mungkin tidak akan pernah karena saya tidak pernah menyentuh sintaks ::path .

Ada ruang untuk perbaikan, tentu saja. Kata kunci bisa lebih baik dipilih, pub(super) masih merepotkan, dan itu adalah gangguan mendapatkan peringatan kode mati di semua tempat ketika saya menggunakan visibilitas tingkat peti untuk metode pembantu. Namun, sebagai pengguna, saya lebih suka fitur ini dibiarkan (berpagar fitur) sampai solusi yang lebih baik ditemukan. Sintaks pub(crate) adalah sesuatu yang merusak pemandangan dan sedikit menghambat pemecahan modul besar menjadi lebih kecil, lebih ketat.

berpikir rintangan ergonomis terbesar di sekitar "tingkat privasi campuran" berasal dari serat dan kesalahan yang terkait dengan kami mencoba untuk memastikan bahwa (misalnya) semua jenis yang muncul di pub(x) fn memiliki privasi yang sesuai.

Apakah ini berarti kami juga tidak mengaktifkan lint "pub unreachable" ( mod private { pub fn f() {} } )?

Heh, saya telah berpikir dua kali ketika saya membaca berbagai kode rustc dan melihat crate digunakan, dan saya membayangkan bahwa kasus-kasus itu semuanya pub(crate) ... mungkin layak dilakukan transisi eksperimental hanya untuk melihat bagaimana perbedaan membuat saya merasa. Saya ingat merasa sedih karena kapur ketika kami memindahkannya dari malam ke kandang, meskipun saya pikir sekarang saya sudah terbiasa, itu tidak terlalu mengganggu saya.

@matklad Saya harap tidak, saya pikir lint juga cukup penting. Sejujurnya, saya tidak sepenuhnya yakin mengapa saya tidak menemukan kesalahan dan gangguan seperti yang biasa saya dapatkan. Mungkin saya baru saja tidak cukup menulis kode Rust akhir-akhir ini! Saya benar-benar ingat bahwa saya dulu memiliki siklus yang mengganggu ini di mana sepertinya saya tidak dapat memuaskan kompiler kecuali dengan membuat lebih banyak hal pub daripada yang saya inginkan.

Bagaimana dengan menyimpan pub(crate) dan juga menambahkan alias pubc ? Ini berbunyi sangat mirip, tidak merusak kode apa pun saat ini, dan menghilangkan keharusan mengetik tanda kurung (yang membuatnya sedikit lebih cepat).
Ini juga akan memungkinkan pubs untuk visibilitas di induknya.

Singkatnya, saya akan mendukung penghapusan tingkat visibilitas crate dari kompiler dan menghapus gerbang fitur.

Saya menemukan pub(crate) menjadi semacam merusak pemandangan dan berisik ketika saya membaca kode. Akan sangat menyenangkan untuk memiliki pengubah visibilitas crate sebagai gantinya.

Dan, tentu saja, fakta bahwa tidak menambahkan crate fn sekarang tidak berarti kita tidak dapat menambahkannya nanti. Secara khusus, saya pikir model "tiga tingkat privasi" akan bekerja lebih baik jika kita memiliki beberapa cara untuk melakukan "peti sebaris yang ringan" di dalam peti lain. yaitu, jika alih-alih memiliki submodule di dalam peti, saya dapat mendeklarasikan _crate_ pribadi dengan semua yang menyiratkan (terutama, mungkin, hubungan seperti DAG dengan hal-hal lain). Saya tidak yakin apakah peti sebaris yang ringan akan benar-benar berfungsi, tetapi peti itu mungkin menutupi dan mengganti banyak kasus penggunaan seperti pub(super) . Jika pernah menjelajahi itu, maka saya akan mempertimbangkan untuk membuka kembali diskusi sekitar crate fn , karena mungkin menjadi jauh lebih berguna/umum.

Saya pasti akan menyukai peti "ringan" yang Anda sebutkan ini! Akan jauh lebih baik daripada langsung pergi ke ruang kerja, yang agak berat.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat