Ben bir göz atmış listede üzerinde yapılan araştırmaların scala-lang.org ve meraklı bir soru fark: " ‘? Sen tüm kullanımlarını sayabilir’_ ". Yapabilir misin? Evet ise, lütfen burada yapın. Açıklayıcı örnekler takdir edilmektedir.
Ben bir göz atmış listede üzerinde yapılan araştırmaların scala-lang.org ve meraklı bir soru fark: " ‘? Sen tüm kullanımlarını sayabilir’_ ". Yapabilir misin? Evet ise, lütfen burada yapın. Açıklayıcı örnekler takdir edilmektedir.
Yanıtlar:
Aklıma gelenler
def foo(l: List[Option[_]]) = ...
case class A[K[_],T](a: K[T])
val _ = 5
List(1, 2, 3) foreach { _ => println("Hi") }
trait MySeq { _: Seq[_] => }
Some(5) match { case Some(_) => println("Yes") }
"abc" match { case s"a$_c" => }
C(1, 2, 3) match { case C(vs @ _*) => vs.foreach(f(_)) }
import java.util._
import java.util.{ArrayList => _, _}
def bang_!(x: Int) = 5
def foo_=(x: Int) { ... }
List(1, 2, 3) map (_ + 2)
List(1, 2, 3) foreach println _
def toFunction(callByName: => Int): () => Int = callByName _
var x: String = _ // unloved syntax may be eliminated
Unuttuğum başkaları da olabilir!
Neden foo(_)
ve foo _
farklı olduklarını gösteren örnek :
Bu örnek 0 __'dan gelir :
trait PlaceholderExample {
def process[A](f: A => Unit)
val set: Set[_ => Unit]
set.foreach(process _) // Error
set.foreach(process(_)) // No Error
}
İlk durumda, process _
bir yöntemi temsil eder; Scala, polimorfik yöntemi alır ve type parametresini doldurarak monomorfik hale getirmeye çalışır, ancak türüA
verecek olan doldurulabilecek bir tür olmadığını fark eder (_ => Unit) => ?
(Varoluşçu _
bir tür değildir).
İkinci durumda, process(_)
bir lambda; açık bir bağımsız değişken türüne sahip bir lambda yazarken Scala bağımsız değişkeni bu tür çıkarır foreach
bekler ve _ => Unit
bir (sadece düz ise bir tür _
değildir) bu ikameli ve çıkarılabilir, böylece.
Bu şimdiye kadar karşılaştığım Scala en zor gotcha olabilir.
Bu örneğin 2.13'te derlendiğini unutmayın. Alt çizgiye atanmış gibi yoksay.
val x: Any = _
println _
ve println(_)
farklı. Örneğin, varoluşçu ve polimorfik türleri biraz farklı şekilde ele almaları bakımından bunu görebilirsiniz. Biraz örnek verecek.
İçinde (benim girişi) Gönderen SSS kesinlikle tam olduğu garanti etmiyoruz, (ben sadece iki gün önce iki girdileri eklendi):
import scala._ // Wild card -- all of Scala is imported
import scala.{ Predef => _, _ } // Exception, everything except Predef
def f[M[_]] // Higher kinded type parameter
def f(m: M[_]) // Existential type
_ + _ // Anonymous function placeholder parameter
m _ // Eta expansion of method into method value
m(_) // Partial function application
_ => 5 // Discarded parameter
case _ => // Wild card pattern -- matches anything
val (a, _) = (1, 2) // same thing
for (_ <- 1 to 10) // same thing
f(xs: _*) // Sequence xs is passed as multiple parameters to f(ys: T*)
case Seq(xs @ _*) // Identifier xs is bound to the whole matched sequence
var i: Int = _ // Initialization to the default value
def abc_<>! // An underscore must separate alphanumerics from symbols on identifiers
t._2 // Part of a method name, such as tuple getters
1_000_000 // Numeric literal separator (Scala 2.13+)
Bu da bu sorunun bir parçası .
var i: Int = _
veya özel desen eşleştirme durumu val (a, _) = (1, 2)
veya özel durum atılır valfor (_ <- 1 to 10) doIt()
def f: T; def f_=(t: T)
mutable f üyesi oluşturmak için açılan.
_
yöntem adlarında hile yapılır. Ama, tamam, tamam. Umarım başka biri SSS'yi günceller ... :-)
Alt çizginin kullanımıyla ilgili mükemmel bir açıklama Scala _ [alt çizgi] büyüsüdür .
Örnekler:
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "anything other than one and two"
}
expr match {
case List(1,_,_) => " a list with three element and the first element is 1"
case List(_*) => " a list with zero or more elements "
case Map[_,_] => " matches a map with any key type and any value type "
case _ =>
}
List(1,2,3,4,5).foreach(print(_))
// Doing the same without underscore:
List(1,2,3,4,5).foreach( a => print(a))
Scala'da, paketleri içe aktarırken Java'dakine _
benzer *
.
// Imports all the classes in the package matching
import scala.util.matching._
// Imports all the members of the object Fun (static import in Java).
import com.test.Fun._
// Imports all the members of the object Fun but renames Foo to Bar
import com.test.Fun.{ Foo => Bar , _ }
// Imports all the members except Foo. To exclude a member rename it to _
import com.test.Fun.{ Foo => _ , _ }
Scala'da bir alıcı ve ayarlayıcı, bir nesnedeki tüm özel olmayan değişkenler için örtük olarak tanımlanacaktır. Alıcı adı değişken adıyla aynıdır _=
ve ayarlayıcı adı için eklenir.
class Test {
private var a = 0
def age = a
def age_=(n:Int) = {
require(n>0)
a = n
}
}
Kullanımı:
val t = new Test
t.age = 5
println(t.age)
Yeni bir değişkene bir işlev atamaya çalışırsanız, işlev çağrılır ve sonuç değişkene atanır. Bu karışıklık, yöntem çağırma için isteğe bağlı parantez nedeniyle oluşur. İşlev adından sonra _ değerini başka bir değişkene atamak için kullanmalıyız.
class Test {
def fun = {
// Some code
}
val funLike = fun _
}
List(1,2,3,4,5).foreach(print(_))
sadece yapmak için çok daha okunabilir List(1,2,3,4,5).foreach(print)
, gerçekten alt çizgiye bile ihtiyacın yok, ama sanırım bu sadece bir stil meselesi
Buradaki herkesin listeyi unuttuğunu görebildiğim tek bir kullanım var ...
Bunu yapmak yerine:
List("foo", "bar", "baz").map(n => n.toUpperCase())
Bunu basitçe yapabilirsiniz:
List("foo", "bar", "baz").map(_.toUpperCase())
n => n
Burada kullanılan bazı örnekler verilmiştir _
:
val nums = List(1,2,3,4,5,6,7,8,9,10)
nums filter (_ % 2 == 0)
nums reduce (_ + _)
nums.exists(_ > 5)
nums.takeWhile(_ < 8)
Yukarıdaki tüm örneklerde, bir alt çizgi listedeki bir öğeyi temsil eder (ilk alt çizgiyi azaltmak için akümülatörü temsil eder)
JAiro'nun bahsettiği kullanımların yanı sıra , bunu beğendim:
def getConnectionProps = {
( Config.getHost, Config.getPort, Config.getSommElse, Config.getSommElsePartTwo )
}
Birisi tüm bağlantı özelliklerine ihtiyaç duyarsa şunları yapabilir:
val ( host, port, sommEsle, someElsePartTwo ) = getConnectionProps
Yalnızca bir ana bilgisayara ve bir bağlantı noktasına ihtiyacınız varsa şunları yapabilirsiniz:
val ( host, port, _, _ ) = getConnectionProps
"_" İfadesinin kullanılabileceği özel bir örnek vardır:
type StringMatcher = String => (String => Boolean)
def starts: StringMatcher = (prefix:String) => _ startsWith prefix
Şuna eşit olabilir:
def starts: StringMatcher = (prefix:String) => (s)=>s startsWith prefix
Bazı senaryolarda “_” uygulandığında otomatik olarak “(x $ n) => x $ n” ye dönüşür