SORU
16 Aralık 2012, Pazar


şimdiye kadar anlayamıyorum scala

Bazı Kaygan çalışır ve ne gerektiriyorsa anlamaya çalışıyorum.

Buna bir örnek işte

package models

case class Bar(id: Option[Int] = None, name: String)

object Bars extends Table[Bar]("bar") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)

  // This is the primary key column
  def name = column[String]("name")

  // Every table needs a * projection with the same type as the table's type parameter
  def * = id.? ~ name <>(Bar, Bar.unapply _)
}

Biri unapply neden <>, ne * yöntem burada, amacı nedir bana açıklayabilir mi? ve ne ~ Projeksiyon yöntemi - ' döndürür örneği Projection2?

CEVAP
17 Aralık 2012, PAZARTESİ


[GÜNCELLEME]-(henüz başka) eklendi for açıklama kapsam

  1. * yöntemi:

    Bu dönerprojeksiyon varsayılannasıl tarif edilir ki: -

    <>'tüm sütunlar (veya hesaplanmış değerler) benim . p ^em>genellikleilgi'.

    Masanız bazı alanlar; sadece alt lazım olabilir varsayılan projeksiyon. Varsayılan projeksiyon tipi eşleşmesi gerekir tablo parametreleri.

    Hadi bir tane al. <> şeyler olmadan, sadece 27**:

    // First take: Only the Table Defintion, no case class:
    
    object Bars extends Table[(Int, String)]("bar") {
      def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
      def name = column[String]("name")
    
      def * = id ~ name // Note: Just a simple projection, not using .? etc
    }
    
    // Note that the case class 'Bar' is not to be found. This is 
    // an example without it (with only the table definition)
    

    Böyle bir tablo tanımını sorgu gibi yapalım

    implicit val session: Session = // ... a db session obtained from somewhere
    
    // A simple select-all:
    val result = Query(Bars).list   // result is a List[(Int, String)]
    

    (Int, String) varsayılan projeksiyon List[(Int, String)] yol açar bu gibi basit sorguları için.

    // SELECT b.name, 1 FROM bars b WHERE b.id = 42;
    val q = 
       for (b <- Bars if b.id === 42) 
         yield (b.name ~ 1)
         // yield (b.name, 1) // this is also allowed: 
                              // tuples are lifted to the equivalent projection.
    

    q türü nedir? Projeksiyon (String, Int) 34*. Çağrıldığında, projeksiyon başına List (String, Int) bir dizilerini geri döndürür.

     val result: List[(String, Int)] = q.list
    

    Bu durumda, yield fıkrasında istediğiniz projeksiyon tanımladınız for anlama.

  2. <> Bar.unapply şimdi hakkında.

    Bu ne denir sağlarEşlenen Projeksiyonlar.

    Sen Scala sorguları ifade etmek ne gördük şimdiye kadar bu dönüşsütun projeksiyonyürütürken (ya da hesaplanan değer); bu sorgularsonucu düşünmek satır varbir sorguScala bir demet gibi. Başlığın türü tanımlanan Projeksiyon eşleşir (senin tarafından Önceki örnekte olduğu gibi for anlama, varsayılan 44 ** projeksiyon). Bu field1 ~ field2 Projection2[A, B] bir projeksiyon verir Neden Nerede A field1 B field2 türüdür türüdür.

    q.list.map {
      case (name, n) =>  // do something with name:String and n:Int
    }
    
    Queury(Bars).list.map {
      case (id, name) =>  // do something with id:Int and name:String 
    }
    

    Eğer çok fazla varsa hantal olabilir dizilerini, uğraştığımız sütunlar. TupleN daha ziyade bir sonuç düşünmek istiyoruz adında alanlar oluşturur.

    (id ~ name)  // A projection
    
    // Assuming you have a Bar case class:
    case class Bar(id: Int, name: String) // For now, using a plain Int instead
                                          // of Option[Int] - for simplicity
    
    (id ~ name <> (Bar, Bar.unapply _)) // A MAPPED projection
    
    // Which lets you do:
    Query(Bars).list.map ( b.name ) 
    // instead of
    // Query(Bars).list.map { case (_, name) => name }
    
    // Note that I use list.map instead of mapResult just for explanation's sake.
    

    Nasıl oluyor bu iş? <> Projection2[Int, String] ve bir projeksiyon alır döner 56* *türü eşlenen bir projeksiyon. İki bağımsız Bar, Bar.unapply _ (Int, String) bu projeksiyon durumda bir sınıf eşlenen ne kadar kaygan olduğunu söyle.

    Bu iki yönlü eşleştirme; Bar vaka sınıf yapıcısı, o yüzden. bilgi Bar (id: Int, name: String) gitmek istiyordum. Ve unapply eğer tahmin ettiyseniz, tersine çevirmek için.

    Nerede unapply nereden geliyor? Bu standart Scala bir yöntem kullanılabilir sıradan bir vaka sınıf - sadece tanımlama Bar Bar.unapply verir biraspiratörO O id name geri almak için kullanılabilir Bar ile inşa edilmiştir:

    val bar1 = Bar(1, "one")
    // later
    val Bar(id, name) = bar1  // id will be an Int bound to 1,
                              // name a String bound to "one"
    // Or in pattern matching
    val bars: List[Bar] = // gotten from somewhere
    val barNames = bars.map {
      case Bar(_, name) => name
    }
    
    val x = Bar.unapply(bar1)  // x is an Option[(String, Int)]
    

    Varsayılan projeksiyon dava sınıfı eşlenebilir böylece en kullanmak için bekliyoruz:

    object Bars extends Table[Bar]("bar") {
      def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
      def name = column[String]("name")
      def * = id ~ name <>(Bar, Bar.unapply _)
    }
    

    Hatta başına-sorgu olabilir:

    case class Baz(name: String, num: Int)
    
    // SELECT b.name, 1 FROM bars b WHERE b.id = 42;
    val q1 = 
       for (b <- Bars if b.id === 42) 
         yield (b.name ~ 1 <> (Baz, Baz.unapply _))
    

    Burada q1 a tipi Queryeşleştirilmişprojeksiyon 74**için. } / List Baz bir nesne döndürür:

     val result: List[Baz] = q1.list
    
  3. Bir kenara olarak, son olarak, .? bulunmaktadırSeçeneği Kaldırma- Scala yolu olmayabilir değerleri ile ilgili.

     (id ~ name)   // Projection2[Int, String] // this is just for illustration
     (id.? ~ name) // Projection2[Option[Int], String]
    

    Hangi, sarma, güzel Bar orijinal tanımı ile çalışır:

    case class Bar(id: Option[Int] = None, name: String)
    
    // SELECT b.id, b.name FROM bars b WHERE b.id = 42;
    val q0 = 
       for (b <- Bars if b.id === 42) 
         yield (b.id.? ~ b.name <> (Bar, Bar.unapply _))
    
    
    q0.list // returns a List[Bar]
    
  4. Nasıl Kaygan for kullanır kapsam: yorum yanıt olarak

    Her nasılsa, her zaman monadlar ve talep göstermek için yönetmek açıklama... parçası olmak

    Kapsam koleksiyonları yalnızca belirli değildir. Herhangi bir tür olabilirMonadve koleksiyon monad türleri Scala mevcut birçok türden sadece biri.

    Ama koleksiyon tanıdık gibi, iyi bir başlangıç yaparlar bir açıklama nokta:

    val ns = 1 to 100 toList; // Lists for familiarity
    val result = 
      for { i <- ns if i*i % 2 == 0 } 
        yield (i*i)
    // result is a List[Int], List(4, 16, 36, ...)
    

    Scala, anlama için bir sözdizimsel şekerdir yöntem (muhtemelen iç içe) yöntemini çağırır: yukarıdaki kodu (daha fazla ya da daha az) eşittir:

    ns.filter(i => i*i % 2 == 0).map(i => i*i)
    

    Temel olarak, filter, map, 87*bir şey* yöntem (diğer bir deyişle, birMonadbir kullanılabilir ns yerine for anlama. İyi bir örnek Option monad. Burada önceki örnek. for aynı ifade, hem de üzerinde çalıştığı List Option monadlar:

    // (1)
    val result = 
      for { 
        i <- ns          // ns is a List monad
        i2 <- Some(i*i)  // Some(i*i) is Option
          if i2 % 2 == 0 // filter
      } yield i2
    
    // Slightly more contrived example:
    def evenSqr(n: Int) = { // return the square of a number 
      val sqr = n*n         // only when the square is even
      if (sqr % 2 == 0) Some (sqr)
      else None
    }
    
    // (2)
    result = 
      for { 
        i <- ns  
        i2 <- evenSqr(i) // i2 may/maynot be defined for i!
      } yield i2
    

    Son örnekte, dönüşüm belki de görünecektir bu gibi:

    // 1st example
    val result = 
      ns.flatMap(i => Some(i*i)).filter(i2 => i2 %2 ==0)
    
    // Or for the 2nd example
    result = 
      ns.flatMap(i => evenSqr(i)) 
    

    Kaygan, sorgular monadic - sadece nesneler vardır *, flatMap *95 filter yöntemleri. for çok anlama (* yöntemi açıklama gösterilen) için çeviren:

    val q = 
      Query(Bars).filter(b => b.id === 42).map(b => b.name ~ 1)
    // Type of q is Query[(String, Int)]
    
    val r: List[(String, Int)] = q.list // Actually run the query
    

    , flatMap, map 103* için kullanılır gördüğünüz gibi Query(Bars)tekrarlanan dönüşümü ile Query üret filter 107* her çağrı ile. Bu durumda koleksiyonda bu yöntem aslında ve koleksiyonu yineleme filtre ama Kaygan SQL oluşturmak için kullanılır. Daha fazla detay: How does Scala Slick translate Scala code into JDBC?

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Apple&Tech Reviews & Giveaways

    Apple&Tech R

    12 Temmuz 2008
  • Matthew Pearce

    Matthew Pear

    9 AĞUSTOS 2009
  • TomKNJ

    TomKNJ

    26 ŞUBAT 2007