chciałbym mieć dobry przykład dla każdego przebiegu funkcji, niech stosuje, również zPrzykład kiedy powinniśmy używać biegać, pozwól, zastosowanie, również i na Kotlin
Czytałem this article ale nadal brakuje z przykładu
chciałbym mieć dobry przykład dla każdego przebiegu funkcji, niech stosuje, również zPrzykład kiedy powinniśmy używać biegać, pozwól, zastosowanie, również i na Kotlin
Czytałem this article ale nadal brakuje z przykładu
Wszystkie te funkcje służą do przełączania zakresu bieżącej funkcji/zmiennej. Są one używane do przechowywania rzeczy, które należą do siebie w jednym miejscu (głównie inicjalizacje).
Oto kilka przykładów:
run
- zwraca cokolwiek chcesz i ponownie zakresów zmienną jest używany do this
val password: Password = PasswordGenerator().run {
seed = "someString"
hash = {s -> someHash(s)}
hashRepetitions = 1000
generate()
}
Generator hasło jest teraz rescoped jak this
i dlatego możemy ustawić seed
, hash
i hashRepetitions
bez użycia zmiennej. generate()
zwróci instancję z Password
.
apply
jest podobna, ale powróci this
:
val generator = PasswordGenerator().apply {
seed = "someString"
hash = {s -> someHash(s)}
hashRepetitions = 1000
}
val pasword = generator.generate()
To szczególnie przydatne jako zamiennik dla wzoru Builder, a jeśli chcesz, aby ponownie wykorzystać pewne konfiguracje.
let
- używany głównie w celu uniknięcia kontroli zerowych, ale może być również używany jako zamiennik dla run
. Różnica polega na tym, że this
wciąż będzie taka sama, jak przed i uzyskać dostęp do ponownego scoped zmienną korzystając it
:
val fruitBasket = ...
apple?.let {
println("adding a ${it.color} apple!")
fruitBasket.add(it)
}
Powyższy kod doda jabłko do kosza tylko jeśli nie jest zerowa. Również zauważyć, że it
jest teraz nie opcjonalne już więc nie napotkasz NullPointerException tutaj (aka nie trzeba używać ?.
dostęp do jego atrybutów.)
also
- używaj go, gdy chcesz użyć apply
, ale nie chcesz, aby cień this
class FruitBasket {
private var weight = 0
fun addFrom(appleTree: AppleTree) {
val apple = appleTree.pick().also { apple ->
this.weight += apple.weight
add(apple)
}
...
}
...
fun add(fruit: Fruit) = ...
}
Korzystanie apply
tutaj by cień this
, tak że this.weight
by zapoznać się z jabłkiem i nie do kosza owoców.
Uwaga: I bezczelnie wziął przykłady from my blog
Istnieje kilka więcej artykułów takich jak here i here że warto spojrzeć.
Myślę, że to zależy od tego, kiedy potrzebujesz krótszej, bardziej zwięzłej w kilku linijkach i unikania rozgałęzień lub warunkowego sprawdzania oświadczeń (np. Jeśli nie jest pusta, to zrób to).
Uwielbiam ten prosty wykres, więc połączyłem go tutaj. Można go zobaczyć z this, jak napisał Sebastiano Gottardo.
Proszę również spojrzeć na wykres towarzyszącej moje wyjaśnienie poniżej.
myślę go jako rolę gra drogę wewnątrz bloku kodu po wywołaniu tych funkcji + czy chcesz się z powrotem (do funkcji połączeń łańcucha, lub ustawić spowodować zmienna, etc).
Powyżej jest to, co myślę.
Zobaczmy przykłady dla nich wszystkich tutaj
1.) myComputer.apply { }
oznacza, że chcesz działać jako głównego aktora (chcesz, aby myśleć, że jesteś komputer), a chcesz się z powrotem (komputer), dzięki czemu można zrobić
var crashedComputer = myComputer.apply {
// you're the computer, you yourself install the apps
// note: installFancyApps is one of methods of computer
installFancyApps()
}.crash()
tak, ty sam wystarczy zainstalować aplikacje, crash siebie i zapisane siebie jako punkt odniesienia, by inni mogli zobaczyć i coś z tym zrobić.
2.) myComputer.also {}
oznacza, że jesteś całkowicie pewien, że nie sąkomputer, jesteś outsiderem, który chce coś z tym zrobić, a także chce, komputer jako zwróconego wyniku.
var crashedComputer = myComputer.also {
// now your grandpa does something with it
myGrandpa.installVirusOn(it)
}.crash()
3.) with(myComputer) { }
oznacza, że jesteś głównym aktorem (komputer), a ty nie chcą się wskutek powrotem.
with(myComputer) {
// you're the computer, you yourself install the apps
installFancyApps()
}
4.) myComputer.run { }
oznacza, że jesteś głównym aktorem (komputer), a ty nie chcą się wskutek powrotem.
myComputer.run {
// you're the computer, you yourself install the apps
installFancyApps()
}
ale różni się od with { }
w bardzo subtelnym poczuciem, że można zadzwonić łańcuch run { }
jak na poniższym
myComputer.run {
installFancyApps()
}.run {
// computer object isn't passed through here. So you cannot call installFancyApps() here again.
println("woop!")
}
Wynika to run {}
jest funkcja rozszerzenie, ale with { }
nie jest. Więc zadzwonisz pod numer run { }
i this
wewnątrz bloku kodu zostanie odzwierciedlony typ obiektu wywołującego. Możesz zobaczyć this doskonałe wyjaśnienie różnicy między run {}
i with {}
.
5.) oznacza, że jesteś osobą postronną, która patrzy na komputer i chce coś z tym zrobić, nie zwracając uwagi na to, aby instancja komputera została zwrócona do Ciebie ponownie.
myComputer.let {
myGrandpa.installVirusOn(it)
}
staram się patrzeć na also
i let
jako coś, co jest zewnętrzne, na zewnątrz. Ilekroć wypowiadasz te dwa słowa, to tak, jakbyś próbował coś zrobić.let
zainstaluj wirusa na tym komputerze, a also
uruchom go. Więc to zależy od tego, czy jesteś aktorem czy nie.
Dla części wynikowej wyraźnie tam jest. also
wyraża, że jest to kolejna rzecz, więc nadal zachowujesz dostępność samego obiektu. W związku z tym zwraca go jako wynik.
Wszystko inne kojarzy się z this
. Dodatkowo, run/with
wyraźnie nie jest zainteresowany powrotem z powrotem do obiektu. Teraz możesz je wszystkie rozróżnić.
Myślę, że czasami, gdy odchodzimy od 100% programowania/logiki na podstawie przykładów, to jesteśmy w lepszej pozycji do konceptualizacji rzeczy. Ale to zależy dobrze :)