SORU
2 Mart 2012, Cuma


Scala örtülü parametre iyi örnek?

Şimdiye kadar benim için iyi bak yoksa Scala örtülü parametreler-genel değişkenler çok yakın olduğunu, ancak Scala oldukça katı bir dil gibi görünüyor çünkü ben kendi kanımca şüpheye düşeceğim :-).

Soru:kapalı parametreleri gerçekten işe ne zaman gerçek hayatta (veya yakın) iyi bir örnek gösterir misin. DÜŞÜK: böyle dil haklı çıkaracak showPrompt, daha ciddi bir tasarım.

Ya da aksine -- güvenilir dil tasarımı (hayali olabilir) gösterebilir misin örtülü gerekli değil. Hatta bir mekanizma kodu daha açık ve tahmin yoktur çünkü implicits daha iyi olduğunu düşünüyorum.

Lütfen unutmayın, parametreleri, kapalı fonksiyonlar (dönüşüm) hakkında soruyorum!

Güncelleştirmeleri

Global değişkenler

Tüm büyük cevaplar için teşekkür ederim. Belki de benim "değişken" itiraz ediyorum. küresel netleştirmek Böyle bir işlevi göz önünde bulundurun:

max(x : Int,y : Int) : Int

sen söyle

max(5,6);

olabilir (!) bu gibi yapın:

max(x:5,y:6);

ama benim gözümde implicits bu gibi çalışır:

x = 5;
y = 6;
max()

böyle bir yapı (PHP gibi) çok farklı değildir

max() : Int
{
  global x : Int;
  global y : Int;
  ...
}

Derek cevap

Bu mesaj implicit lütfen bir karşı-örnek yazı kullanarak gönderme olarak esnek kullanım biliyorsan büyük bir örnek, ancak. Dil tasarım saflık hakkında gerçekten merak ediyorum ;-).

CEVAP
2 Mart 2012, Cuma


Bir anlamda, Evet, implicits genel halini yansıtır. Ancak, insanların genel sabitler şikayet görmüyorum global değişkenleri ile gerçek bir sorun değil, değiştirilebilir, -- onlar, değil mi? Aslında, kodlama standartları genellikle genellikle küresel olan sabit veya çeteleler, kodunuzda herhangi bir sabitlere dönüştüren dikte.

İmplicits olduğunu unutmayındeğilayrıca global ile ortak bir sorun olan düz bir ad. Açıkça bu tür paket hiyerarşiye tip ve, bu nedenle, ne yapacaklar.

Yani, bütünsel al, onları değişmez ve başlatılmış beyannamesi yerinde olun ve ad koydu. Hala bütünsel benziyorlar mı? Hala sorunlu görünüyorlar?

Ama orada durmaz. İmplicitstürlerine bağlı, ve bir o kadar da "türleri gibi." küresel vardır Bu tip geneldir aslında sizi rahatsız ediyor mu?

Kullanım durumları gelince, o kadar çok ki, ama kendi geçmişine dayalı kısa bir inceleme yapabiliriz. Aslında, afaık, Scala implicits yoktu. Scala vardı ne tür, birçok dili vardı bir özelliği görüntüleyin. Hala 24 ** türü anlamına gelir T <% Ordered[T] gibi bir şey yazdığınız zaman bugün 25 ** bir tür olarak kabul edilebilir olduğunu görüyoruz. Görünüm tipleri otomatik atmalarını tür parametreleri kullanılabilir hale getirmenin bir yolu (jenerik).

O zaman Scalagenelleştirilmişbu implicits ile donatılmıştır. Otomatik artık yok atmalarını, ve, bunun yerine, varörtük dönüştürmelersadece Function1 değerleri, bu parametre olarak geçirilebilir--. O andan itibaren, 27* *örtülü bir dönüştürme için bir değer ifade parametre olarak geçecek. Döküm otomatik olduğundan, işlevi çağıran bu parametreler oldu açıkça parametre -- geçirmek için gerekli değildirkapalı parametreleri.

İki kavram çok yakın, ama tamamen örtüşüyor bu örtülü dönüşüm ve kapalı parametreleri yer var unutmayın.

Neyse, görünüm türleri örtük dönüştürmeler örtük olarak geçirilen için sözdizimsel şeker oldu. Bu şekilde yazılmış olacaktır:

def max[T <% Ordered[T]](a: T, b: T): T = if (a < b) b else a
def max[T](a: T, b: T)(implicit $ev1: Function1[T, Ordered[T]]): T = if ($ev1(a) < b) b else a

Örtülü parametreleri sadece bu modelin bir genelleme mümkün geçirmek için yapıyoruzherhangi birkapalı parametreleri, yerine Function1 sadece bir tür. Onlar için gerçek kullanım sonra takip ve şeker için sözdizimibukullandığı ikinci geldi.

Bunlardan biriİçerik Sınırları, uygulamak için kullanılıryazın sınıf desen(yerleşik bir özellik, Haskell'ın tip sınıfı için benzer bir işlevsellik sağlayan bir dil kullanmanın bir yolu olmadığından desen). Bir bağlam bağlı bir sınıf doğasında vardır bu işlevi uygulayan bir adaptör bulunur, ama tarafından bildirilen için kullanılır. Miras avantajları vardır ve dezavantajları olmadan arabirimleri. Örneğin:

def max[T](a: T, b: T)(implicit $ev1: Ordering[T]): T = if ($ev1.lt(a, b)) b else a
// latter followed by the syntactic sugar
def max[T: Ordering](a: T, b: T): T = if (implicitly[Ordering[T]].lt(a, b)) b else a

Zaten insanlar genellikle fark olmadığını yaygın bir kullanım şekli var o kullanmış. O da şudur:

new Array[Int](size)

Böyle bir dizi başlatma etkinleştirmek için bir bağlam sınıf bildirimlerin bağlı, kullanır. Bu örnekle görebiliriz:

def f[T](size: Int) = new Array[T](size) // won't compile!

Bu gibi yazmak:

def f[T: ClassManifest](size: Int) = new Array[T](size)

Standart kütüphane, bağlam sınırları en çok kullanılan

Manifest      // Provides reflection on a type
ClassManifest // Provides reflection on a type after erasure
Ordering      // Total ordering of elements
Numeric       // Basic arithmetic of elements
CanBuildFrom  // Collection creation

Son üç çoğunlukla koleksiyonları, max, sum map gibi yöntemler ile birlikte kullanılır. İçerik sınırları geniş kullanımı yapar bir kütüphane Scalaz.

Başka bir ortak kullanım ortak bir parametre paylaşmak gereken işlemleri üzerinde kazan-plaka azaltmaktır. Örneğin, işlemler

def withTransaction(f: Transaction => Unit) = {
  val txn = new Transaction

  try { f(txn); txn.commit() }
  catch { case ex => txn.rollback(); throw ex }
}

withTransaction { txn =>
  op1(data)(txn)
  op2(data)(txn)
  op3(data)(txn)
}

Sonra böyle: basitleştirilmiş

withTransaction { implicit txn =>
  op1(data)
  op2(data)
  op3(data)
}

Bu desen işlemsel bellek ile kullanılır, ve G/Ç kitaplığı Scala olarak kullanan (ama emin değilim) sanırım.

Aklıma üçüncü ortak kullanımı mümkün, aksi takdirde, çalışma zamanı istisnaları olmasına neden olacak bir derleme şeyleri algılamak için yapar geçirilen türleri hakkında deliller, yapıyor. Örneğin, Option bu tanım, bkz:

def flatten[B](implicit ev: A <:< Option[B]): Option[B]

Bu mümkün kılar:

scala> Option(Option(2)).flatten // compiles
res0: Option[Int] = Some(2)

scala> Option(2).flatten // does not compile!
<console>:8: error: Cannot prove that Int <:< Option[B].
              Option(2).flatten // does not compile!
                        ^

Bu özellik geniş kullanımı yapar bir kütüphane şekilsizdir.

Sanmıyorum örneği Akka kütüphane uyan herhangi biri bu dört kategoride, ama tüm mesele Genel Özellikler: kişi kullanabilir bunu her türlü şekilde yerine yollardan reçete tarafından dile tasarımcısı.

Eğer, diyelim ki, Python gibi) reçete olmak istiyorsanız, o zaman Scala sadece sizin için değil.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • cdgotx

    cdgotx

    8 Kasım 2011
  • LounaTutorials

    LounaTutoria

    10 EYLÜL 2009
  • Stevie

    Stevie

    2 Mayıs 2010