2014-12-17 20 views
7

Diğer işlevsel dillerden geliyor (ve Rust'un yeni üyesi olmak), Rust'un if let sözdiziminin motivasyonu ile biraz şaşırdım. RFC "deyimsel test için çözümü bugün ve Option<T> unwrapping", if let olmadan yaRust neden `` sözdizimini verse?

match opt_val { 
    Some(x) => { 
    do_something_with(x); 
    } 
    None => {} 
} 

veya Scala yılında

if opt_val.is_some() { 
    let x = opt_val.unwrap(); 
    do_something_with(x); 
} 

, tam olarak aynı şeyi mümkün olacağını olduğunu bahseder. Ancak, deyimsel çözüm, bir Option üzerinden map yerine (veya yalnızca'un yan etkisi içinse foreach) 'dir.

Yani benim soru: Neden Rust aynı şeyi bir deyimsel çözüm değildir: Çözümünüz ilk örneğe if let desugars tam oysa kaynaklarını kullanan bir kapatma, yaratır

opt_val.map(|x| do_something_with(x)); 

cevap

8

.map()Option<T> türüne özgü olmakla if let (ve while let!) Tüm Rust tipleri ile çalışmak özellikleridir. if let çok yan etkileri gerçekleştirmek için gereken süre

+1

Not: Bu cevabı kabul ediyorum çünkü kısaca ana _technical_ farkını özetliyor, ama daha kapsamlı bir açıklama için @ Vladimir'in cevabına bakınız. – bluenote10

2

Çünkü değil ki. Ayrıca daha okunabilir buluyorum.

Pas, programlamayı daha güzel yapan sıfır maliyetli soyutlamalarla ilgilidir ve if let ve while let bunların iyi örnekleridir (en azından IMO - Kişisel tercih meselesi olduğunun farkındayım). Kesinlikle gerekli değiller, fakat kullanmak için iyi hissettiriyorlar (ayrıca bkz: Clojure, muhtemelen kaldırıldıkları yerler).

+1

Anladığım kadarıyla, onlar [Swift] (https://github.com/rust-lang/rfcs/blob/master/text/0160-if-let.md) – Shepmaster

+0

'dan kaldırıldılar. Performans kritik değilse haritalama tamam mı? Sözdizimi ve 'map' sözdizimsel olarak hemen hemen aynı olduğu göz önüne alındığında, optimizatörün ilk etapta bir kapanış yaratmasını engellemesinin gerçekten mümkün olup olmadığını merak ediyorum ... – bluenote10

+3

@ bluenote10, yeni kutucuksuz Kapanışlar, 'map' aslında bir' match' ifadesi kullanmak kadar hızlıdır ve kapanış statik olarak adlandırıldığından ve kolayca belirtilebildiğinden, tam olarak aynı koda derleme yapar. – reem

13

map(), opsiyonel bir transforme yöneliktir. Pas saf bir dil olmamasına rağmen, kod bloklarından herhangi biri yan etkiler içerebilir, harita semantiği hala oradadır. Yan etkileri gerçekleştirmek için map()'u kullanmak kesinlikle mümkün olsa da, yalnızca kodunuzun okuyucularını karıştırır. LLVM iyileştirici arama fonksiyonu doğrudan kapatılmasını inlining mükemmel yeteneğine sahiptir, bu yüzden bir match açıklamaya eşdeğer olarak döner - en azından basit kodda, performans yasal olmaması gerektiğini unutmayın. Bir Option bir maç veya Option::is_some() çek ile if ya oldu üzerindeki

if let tek yolu önce yan etkileri gerçekleştirmek için. İç içe kontrollerin çok ihtiyaç vardır, özellikle match yaklaşım en güvenli biridir, ama çok ayrıntılı geçerli:

match o1 { 
    Some(v1) => match v1.f { 
     Some(v2) => match some_function(v2) { 
      Some(r) => ... 
      None => {} 
     } 
     None => {} 
    } 
    None => {} 
} 

Not belirgin sağa kayması ve sözdizimsel bir sürü gürültü. Ve dallar basit eşleşmeler değil, birden çok ifadeyle uygun bloklar ise daha da kötüleşir.

if option.is_some() yaklaşım, diğer taraftan, biraz daha az ayrıntılı ama yine de çok kötü bir şekilde okur. Ayrıca durum kontrolü ve unwrap() statik olarak bağlı değildir, bu yüzden derleyici fark etmeden yanlış yapmak mümkündür.

if let ayrıntı sorunu çözer, bir yan fayda olarak, sadece Option, desenlerde keyfi türleri kullanarak sağlar match, (o if option.is_some() daha Yanlış mı zordur bu yüzden) gibi altyapıyı uyan aynı desen üzerinde bazlar. Örneğin, bazı türler map() benzeri yöntemler sağlayamayabilir; if let hala onlarla çok güzel çalışacak. Yani if let açık bir galibiyet, bu yüzden deyimsel.

+1

_Kullanıcıları yan etki yapmak için kullanmak sadece kodunuzun okuyucusunu karıştırır. Bu yüzden, Scala her zaman "map" nin iki versiyonunu sunar, biri dönüşüm için, diğeri de yan etkiler. Scala yaklaşımı ile ilgili hoşuma giden şey, ek sözdizimi eklemeden aynı sorunu çözmesidir. Scala kullanıcılarını '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' '' '' '' '' '' '' 'ile bekleyiniz. – bluenote10

+1

@ bluenote10, Ben yaşamak için Scala yazıyorum, bu yüzden tamamen farkındayım :) Tekrar, 'let' * seçeneği için * çalışmasına izin verir * ve sözdizimi ile tartışmasız daha hafif kapanışları. –