2016-03-26 7 views
2

"Hijyen", X arasındaki makroların m! benim makrolarımdaki çarpışmaları önleyeceğini düşündüm ama durum böyle olmadı. Neyi yanlış anladım?Makro hijyen, çoklu const tanımları arasındaki çarpışmaları neden engellemez?

macro_rules! m { 
    ($e:expr) => { 
     const X: i32 = $e; 
    } 
} 

m!(0); 
m!(1); 

fn main() { 
    m!(2); 
    m!(3); 
} 

Playpen

hata iletisi:

<anon>:3:9: 3:27 error: duplicate definition of value `X` [E0428] 
<anon>:3   const X: i32 = $e; 
       ^~~~~~~~~~~~~~~~~~ 
<anon>:8:1: 8:7 note: in this expansion of m! (defined in <anon>) 
<anon>:3:9: 3:27 help: see the detailed explanation for E0428 
<anon>:3:9: 3:27 note: first definition of value `X` here 
<anon>:3   const X: i32 = $e; 
       ^~~~~~~~~~~~~~~~~~ 
<anon>:7:1: 7:7 note: in this expansion of m! (defined in <anon>) 
<anon>:3:9: 3:27 error: duplicate definition of value `X` [E0428] 
<anon>:3   const X: i32 = $e; 
...snip... 

cevap

1

https://doc.rust-lang.org/book/macros.html#hygiene kaynaktan:

Bu [yani Yeniden adlandırma] let bağlamaları ve döngü etiketleri için de geçerlidir, ancak öğeler

https://doc.rust-lang.org/reference.html#items için:

bir öğe bir sandık bir bileşenidir. Öğeler bir sandık içinde iç içe geçmiş modüller kümesi tarafından düzenlenir. Her sandığın tek bir "en dış" anonim modülü vardır; sandık içindeki tüm diğer öğeler sandığın modül ağacında yollar içerir.

Öğeler, derleme sırasında tümüyle belirlenir, genellikle yürütme sırasında sabit kalır ve salt okunur bellekte bulunabilir.

öğenin birkaç türü vardır:

  • extern sandık beyanlar
  • kullanım bildirimleri
  • modülleri
  • fonksiyonları
  • tip tanımları
  • yapılar
  • numaralandırma
  • sabit ürün
  • statik öğeler
  • özellikleri
  • uygulamaları

Bu mantıklı: Eğer bir makro bir öğeyi tanıtmak eğer muhtemelen aslında diğer öğeleri kullanmak istiyorum/modules/sandıklar (ve böylece makro dışında), ancak adını bilmiyorsanız, derleyici bunu yeniden adlandıramazsınız.

+0

Teşekkürler. Yani tasarım gereği. “Makroda bir öğeyi tanıtıyorsanız, muhtemelen bunu kullanmak istersiniz”, sanırım bu, hijyenik bir makro sistem olarak tanıtılan şeyi kullanmamız gerektiği anlamına gelmez ... – nodakai

+0

@nodakai Üzgünüz, dışarıda kaldım Makro "orada. Sizin durumunuzda, println! ("X = {}", X); 'son 'm! (3)' den sonra, ne yazmasını beklersiniz? –

+0

Pas makrolarının hijyenik olduğunu duyduğumda "bilinmeyen değişken X" hatası beklerdim. – nodakai

İlgili konular