Scala, Java'nın sahip olduğu güvenli enum
s ürününe sahip değildir. İlgili sabitlerin bir kümesi verildiğinde, Scala'da bu sabitleri temsil etmenin en iyi yolu ne olurdu?Tip güvenli enum türleri nasıl modellenir?
cevap
http://www.scala-lang.org/docu/files/api/scala/Enumeration.html
Örnek (siz de case object
kullanabilir pratikte sınırlı kul olduğunu
object Main extends App {
object WeekDay extends Enumeration {
type WeekDay = Value
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._
def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun)
WeekDay.values filter isWorkingDay foreach println
}
Cidden, Uygulama kullanılmamalıdır. Bu düzeltildi; Schildmeijer'den bahsettiği sorunların olmadığı yeni bir sınıf olan App tanıtıldı. Yani "foo nesnesini App {...}" 'e genişletir. Ve komut satırı değişkeni üzerinden komut satırı argümanlarına hemen erişebilirsiniz. – AmigoNico
scala.Enumeration (yukarıdaki "object WeekDay" kod örneğinizde kullandığınız), ayrıntılı desen eşlemesi sunmuyor. Şu anda Scala'da kullanılmakta olan tüm farklı numaralandırma desenlerini araştırdım ve bu StackOverflow yanıtında bunlara genel bir bakış ve genel bakış sağladım (hem scala'nın en iyilerini sunan yeni bir model de dahil olmak üzere.İzleme ve hem de "kapalı nesne + durum nesnesi" deseni: http: //stackoverflow.com/a/25923651/501113 – chaotic3quilibrium
Ben örnek yukarıda skaffman tarafından Scala belgelerine üzerinden kopyalanan söylemeliyim kullanmak s). Bir Java Enum
benzeyen en yakın şey almak için
(yani mantıklı toString
ve valueOf
yöntemlerle - belki bir veritabanına enum değerleri devam ettirirler) bunu biraz değiştirmeniz gerekir. Eğer skaffman 'ın kodu kullanılmış olsaydı:
WeekDay.valueOf("Sun") //returns None
WeekDay.Tue.toString //returns Weekday(2)
Oysa şu bildiriyi kullanarak: of
WeekDay.valueOf("Sun") //returns Some(Sun)
WeekDay.Tue.toString //returns Tue
Btw değeriOf yöntemi şu anda ölü :-( – greenoldman
@macias 'valueOf' yerine 'withName', bir Seçenek döndürmez ve orada bir NSE atar – Bluu
@Bluu Kendinize değer katabilirsiniz: def değeriOf (name: String) = HaftaDay.values.find (_. toString == name) bir seçeneğe sahip olmak – centr
Biraz daha az ayrıntılı yol: Sen daha mantıklı sonuçlar elde
object WeekDay extends Enumeration {
type WeekDay = Value
val Mon = Value("Mon")
val Tue = Value("Tue")
... etc
}
adlandırılmış numaralar bildiriliyor:
object WeekDay extends Enumeration("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat") {
type WeekDay = Value
val Sun, Mon, Tue, Wed, Thu, Fri, Sat = Value
}
WeekDay.valueOf("Wed") // returns Some(Wed)
WeekDay.Fri.toString // returns Fri
Tabii ki burada sorun, isim ve val'lerin aynı satırda bildirilmesi durumunda daha kolay olan senkronizasyonda isimlerin ve valslerin sıralamasını tutmanız gerekecek olmasıdır.
Bu, ilk bakışta daha temiz görünüyor, ancak denetleyicinin her iki listenin de eşitlenmesini senkronize etmesini gerektiren dezavantaja sahiptir. Haftanın günleri için örnek, olası görünmüyor. Ancak genel olarak, yeni bir değer eklenebilir veya bir silinebilir ve iki liste senkronize edilemez, bu durumda, ince hatalar ortaya çıkabilir. –
Önceki yorum için, risk iki farklı listenin sessizce senkronizasyondan çıkabileceğidir.Mevcut küçük örneğiniz için bir sorun olmasa da, daha fazla üye varsa (düzinelerce yüzlerce gibi), iki listenin sessizce sessizce çıkması olasılığı büyük ölçüde daha yüksektir. Ayrıca scala.Enumeration, Scala'nın derleme zamanı uyarlama/hatalarla eşleşen kapsamlı modelinden yararlanamaz. İki listenin senkronizasyonda kalmasını sağlamak için bir çalışma zamanı denetimi gerçekleştiren bir çözüm içeren bir StackOverflow yanıtı oluşturdum: http://stackoverflow.com/a/25923651/501113 – chaotic3quilibrium
Yapmanın birçok yolu vardır.
1) Sembolleri kullanın. Bir sembolün beklenmediği sembollerin kabul edilmemesinden başka, size herhangi bir tip güvenlik vermez. Sadece burada tamlık için bahsediyorum.
object Dimension extends Enumeration("Row", "Column") {
type Dimension = Value
val Row, Column = Value
}
Bu, bu gibi kullanılabilir: Eğer seri hale getirilmeye veya görüntülemek gerekiyorsa,
object Dimension extends Enumeration {
type Dimension = Value
val Row, Column = Value
}
ya:
def update(what: Symbol, where: Int, newValue: Array[Int]): MatrixInt =
what match {
case 'row => replaceRow(where, newValue)
case 'col | 'column => replaceCol(where, newValue)
case _ => throw new IllegalArgumentException
}
// At REPL:
scala> val a = unitMatrixInt(3)
a: teste7.MatrixInt =
/1 0 0 \
| 0 1 0 |
\ 0 0 1/
scala> a('row, 1) = a.row(0)
res41: teste7.MatrixInt =
/1 0 0 \
| 1 0 0 |
\ 0 0 1/
scala> a('column, 2) = a.row(0)
res42: teste7.MatrixInt =
/1 0 1 \
| 0 1 0 |
\ 0 0 0/
2) sınıfını Enumeration
kullanarak: Burada kullanım örneği :
def update(what: Dimension, where: Int, newValue: Array[Int]): MatrixInt =
what match {
case Row => replaceRow(where, newValue)
case Column => replaceCol(where, newValue)
}
// At REPL:
scala> a(Row, 2) = a.row(1)
<console>:13: error: not found: value Row
a(Row, 2) = a.row(1)
^
scala> a(Dimension.Row, 2) = a.row(1)
res1: teste.MatrixInt =
/1 0 0 \
| 0 1 0 |
\ 0 1 0/
scala> import Dimension._
import Dimension._
scala> a(Row, 2) = a.row(1)
res2: teste.MatrixInt =
/1 0 0 \
| 0 1 0 |
\ 0 1 0/
Unfortu Doğal olarak, tüm maçların hesaba katılmasını sağlamaz. Maçta Row veya Column'u eklemeyi unutursam, Scala derleyicisi beni uyarmazdı. Yani bana tip güvenlik sağlıyor, ancak elde edilebilecek kadar değil.
3) Vaka nesneleri:
MatrixInt.scala:70: warning: match is not exhaustive!
missing combination Column
what match {
^
one warning found
Oldukça fazla kullanılan aynı şekilde ve:
sealed abstract class Dimension
case object Row extends Dimension
case object Column extends Dimension
Şimdi, bir match
bir dava dışarı bırakırsanız, derleyici beni uyarır
scala> val a = unitMatrixInt(3)
a: teste3.MatrixInt =
/1 0 0 \
| 0 1 0 |
\ 0 0 1/
scala> a(Row,2) = a.row(0)
res15: teste3.MatrixInt =
/1 0 0 \
| 0 1 0 |
\ 1 0 0/
zaman neden şimdiye kadar bize: hatta bir import
ihtiyacı yoktur Durum nesneleri yerine bir numaralandırma. Nitekim, vaka nesneleri burada olduğu gibi birçok kez avantajlara sahiptir. Yineleme sınıfı, bir yineleyici, harita, flatMap, filtre, vb döndüren öğeleri (Scala 2.8 üzerinde iterator) gibi birçok toplama yöntemlerine sahiptir.
Bu yanıt aslında blogumdaki this article'dan seçilen bölümlerden seçilmiştir. .
Örneğin, yerine numaralandırma mühürlü soyut sınıfını kullanabilirsiniz: çevresindeki tüm seçenekleri kapsamlı araştırmaların ardından
sealed abstract class Constraint(val name: String, val verifier: Int => Boolean)
case object NotTooBig extends Constraint("NotTooBig", (_ < 1000))
case object NonZero extends Constraint("NonZero", (_ != 0))
case class NotEquals(x: Int) extends Constraint("NotEquals " + x, (_ != x))
object Main {
def eval(ctrs: Seq[Constraint])(x: Int): Boolean =
(true /: ctrs){ case (accum, ctr) => accum && ctr.verifier(x) }
def main(args: Array[String]) {
val ctrs = NotTooBig :: NotEquals(5) :: Nil
val evaluate = eval(ctrs) _
println(evaluate(3000))
println(evaluate(3))
println(evaluate(5))
}
}
Kasa nesneleriyle gizli özellik de bir olasılık. – Ashalynd
"Mühürlü trait + case nesneleri" deseninde StackOverflow yanıtında detaylandırdığım sorunlar var. Bununla birlikte, bu örüntüyle ilgili tüm konuları çözme işlemini çözdüm. Ayrıca, http://stackoverflow.com/a/25923651/501113 – chaotic3quilibrium
"numaralandırma" Scala, bu çok daha eksiksiz bir genel yayınlanmıştır başka bir StackOverflow thread etki alanı. JVM sınıf/nesne başlatma siparişi problemini çözdüğüm "mühürlenmiş trait + case object" desenine bir çözüm içerir.
sadece enumeratum numaralı ürünü buldu. Oldukça şaşırtıcı ve aynı derecede şaşırtıcı, daha iyi bilinmemektedir!
- 1. Türleri Tarih Tip?
- 2. Tip Sınıfı Veri Türleri
- 3. Sabit kodlama enum tip
- 4. java enum tip örneği
- 5. Tip güvenli printf
- 6. null Enum null tip soru
- 7. Android'de güvenli enum özel öznitelikleri
- 8. Scala uçucu türleri: @uncheckedStable güvenli olmayan nedir?
- 9. ENUM ve SQLite içinde oluşturma türleri
- 10. Aktör Deseni - Oda Rezervasyon Yapısı Nasıl Modellenir?
- 11. BitVector ile işaretli tamsayı nasıl modellenir?
- 12. Flux waitFor() ve async işlemi, nasıl modellenir.
- 13. Değişken Şablonlar ve Türleri
- 14. Tuple türleri nasıl belirlenir?
- 15. Java'da MIME Türleri olan bir enum var mı?
- 16. Java'da, bir sınıf statik içinde enum türleri nelerdir?
- 17. typedef aynı tip
- 18. ilişkili tip
- 19. Özyinelemeli işlev türleri nasıl oluşturulur?
- 20. Tip tanımları
- 21. belirli türleri
- 22. Simscape'de mevcut bir kaynak için öngörülen dalga formu nasıl modellenir?
- 23. Türleri
- 24. Enum of Enum NULL
- 25. Türleri
- 26. Üye türleri nasıl uygulanır?
- 27. Nasıl karışık türleri
- 28. Eşitlik Türleri Nasıl Karşılaştırılır?
- 29. Tip Yapıçözüm
- 30. Enum
Neden sadece java enum kullanmıyorsunuz? Bu hala sade java kullanmayı tercih ettiğim birkaç şeyden biri. – Max
Scala Numaralandırma ve alternatifleri hakkında küçük bir genel bakış açmışım, yararlı bulabileceğiniz yerler: pedrorijo.com/blog/scala-enums/ – pedrorijo91