
рд╡реЗ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ "рдбрд┐рдЬрд╝рд╛рдЗрди рдкреИрдЯрд░реНрди рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреА рдХрдорд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рд╣реИрдВред" рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдкреНрд░рд╕реНрддрд╛рд╡, рдпрджрд┐ рдХреЗрд╡рд▓ рдпрд╣ рдирд╣реАрдВ рдХрд╣рд╛ рдЧрдпрд╛ рдерд╛ рдорд╛рдлреА рджреЗрдиреЗ рд╡рд╛рд▓реЗ рд▓рд┐рд╕реНрдк рдФрд░ рд╕реНрдХреАрдорд╛ ред
рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреЛрдЯрд▓рд┐рди рднрд╛рд╖рд╛ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдЗрд╕ рдХрдерди рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджрд┐рд▓ рд╕реЗ рд▓рд┐рдпрд╛ред
рдПрдХрд▓ (рд╕рд┐рдВрдЧрд▓рдЯрди)
рдмреЗрд╢рдХ, рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓рд╛ рдкрд╣рд▓рд╛ рдкреИрдЯрд░реНрди рд▓реЛрдиреЗрд░ рд╣реИред рдФрд░ рдЗрд╕реЗ рд╕реАрдзреЗ рднрд╛рд╖рд╛ рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреАрд╡рд░реНрдб рдХреЗ рд░реВрдк рдореЗрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
object JustSingleton { val value : String = "Just a value" }
рдЕрдм JustSingleton.value
рдлрд╝реАрд▓реНрдб рдкреИрдХреЗрдЬ рдореЗрдВ рдХрд╣реАрдВ рд╕реЗ рднреА рд╕реБрд▓рдн рд╣реЛрдЧреАред
рдФрд░ рдирд╣реАрдВ, рдпрд╣ рд╕реНрдереИрддрд┐рдХ рдЖрд░рдВрднреАрдХрд░рдг рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдХреБрдЫ рджреЗрд░реА рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ:
object SlowSingleton { val value : String init { var uuid = "" val total = measureTimeMillis { println("Computing") for (i in 1..10_000_000) { uuid = UUID.randomUUID().toString() } } value = uuid println("Done computing in ${total}ms") } }
рдкрд╣рд▓реА рдХреЙрд▓ рдкрд░ рдЖрд▓рд╕реА рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рд╣реЛрддрд╛ рд╣реИ:
@org.testng.annotations.Test fun testSingleton() { println("Test started") for (i in 1..3) { val total = measureTimeMillis { println(SlowSingleton.value) } println("Took $total ms") } }
рдЖрдЙрдЯрдкреБрдЯ рд╣реИ:
Test started Computing Done computing in 5376ms "45f7d567-9b3e-4099-98e6-569ebc26ecdf" Took 5377 ms "45f7d567-9b3e-4099-98e6-569ebc26ecdf" Took 0 ms "45f7d567-9b3e-4099-98e6-569ebc26ecdf" Took 0 ms
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдк рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдСрдкрд░реЗрд╢рди рдореЗрдВ 0 рдПрдордПрд╕ рд▓рдЧрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдЕрднреА рднреА рдЖрдкрдХреЗ рдХреЛрдб рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИред
val total = measureTimeMillis {
рдЖрдЙрдЯрдкреБрдЯ:
Test started Took 0 ms Took 0 ms Took 0 ms
рдбреЗрдХреЛрд░реЗрдЯрд░
рдЗрд╕рдХреЗ рдмрд╛рдж рдбреЗрдХреЛрд░реЗрдЯрд░ рдЖрддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдкреИрдЯрд░реНрди рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╡рд░реНрдЧ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдереЛрдбрд╝реА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╣рд╛рдВ, IntelliJ рдЗрд╕реЗ рдЖрдкрдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХреЛрдЯрд▓рд┐рди рдФрд░ рднреА рдЖрдЧреЗ рдмрдврд╝ рдЧрдПред
рдХреИрд╕реЗ рд╣рд░ рдмрд╛рд░ рдЬрдм рд╣рдо рд╣рд╛рд╢рдк рдореЗрдВ рдПрдХ рдирдИ рдХреБрдВрдЬреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕рдВрджреЗрд╢ рдорд┐рд▓рддрд╛ рд╣реИ?
рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ, рдЖрдк рдПрдХ рдРрд╕реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕рднреА рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреАрд╡рд░реНрдб рджреНрд╡рд╛рд░рд╛ рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
class HappyMap<K, V>(val map : MutableMap<K, V> = mutableMapOf()) : MutableMap<K, V> by map{ override fun put(key: K, value: V): V? { return map.put(key, value).apply { if (this == null) { println("Yay! $key") } } } }
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рдирдХреНрд╢реЗ рдХреЗ рддрддреНрд╡реЛрдВ рдХреЛ рд╡рд░реНрдЧ рдХреЛрд╖реНрдардХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдиреНрдп рд╕рднреА рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрд╕реА рддрд░рд╣ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдПрдХ рдирд┐рдпрдорд┐рдд рд╣рд╛рд╢рдк рдореЗрдВред
@org.testng.annotations.Test fun testDecorator() { val map = HappyMap<String, String>() val result = captureOutput { map["A"] = "B" map["B"] = "C" map["A"] = "C" map.remove("A") map["A"] = "C" } assertEquals(mapOf("A" to "C", "B" to "C"), map.map) assertEquals(listOf("Yay! A", "Yay! B", "Yay! A"), (result)) }
рдлреИрдХреНрдЯрд░реА рд╡рд┐рдзрд┐
рдХрдВрдкреЗрдирд┐рдпрди рдСрдмреНрдЬреЗрдХреНрдЯ рдлреИрдХреНрдЯреНрд░реА рдореЗрдердб рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред рдпрд╣ рд╡рд╣ рдкреИрдЯрд░реНрди рд╣реИ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╡рд╕реНрддреБ рдЕрдкрдиреЗ рднреАрддрд░ рдХреБрдЫ рд░рд╣рд╕реНрдпреЛрдВ рдХреЛ рдЫреБрдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЖрд░рдВрднрд┐рдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддреА рд╣реИред
class SecretiveGirl private constructor(val age: Int, val name: String = "A girl has no name", val desires: String = "A girl has no desires") { companion object { fun newGirl(vararg desires : String) : SecretiveGirl { return SecretiveGirl(17, desires = desires.joinToString(", ")) } fun newGirl(name : String) : SecretiveGirl { return SecretiveGirl(17, name = name) } } }
рдЕрдм рдХреЛрдИ рднреА рд╡реНрдпрдХреНрддрд┐ SecretiveGirl рдХреА рдЙрдореНрд░ рдирд╣реАрдВ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИ:
@org.testng.annotations.Test fun FactoryMethodTest() { // Cannot do this, constructor is private // val arya = SecretiveGirl(); val arya1 = SecretiveGirl.newGirl("Arry") assertEquals(17, arya1.age) assertEquals("Arry", arya1.name) assertEquals("A girl has no desires", arya1.desires) val arya2 = SecretiveGirl.newGirl("Cersei Lannister", "Joffrey", "Ilyn Payne") assertEquals(17, arya2.age) assertEquals("A girl has no name", arya2.name) assertEquals("Cersei Lannister, Joffrey, Ilyn Payne", arya2.desires) }
рд░рдгрдиреАрддрд┐
рдЖрдЬ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдо рдПрдХ рд░рдгрдиреАрддрд┐ рд╣реИ ред рдЪреВрдВрдХрд┐ рдХреЛрдЯрд▓рд┐рди рдХреЗ рдкрд╛рд╕ рдЙрдЪреНрдЪ-рдХреНрд░рдо рдХреЗ рдХрд╛рд░реНрдп рд╣реИрдВ , рдЗрд╕рд▓рд┐рдП рдЗрд╕ рдкреИрдЯрд░реНрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рднреА рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ:
class UncertainAnimal { var makeSound = fun () { println("Meow!") } }
рдФрд░ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓реЗрдВ:
@org.testng.annotations.Test fun testStrategy() { val someAnimal = UncertainAnimal() val output = captureOutput { someAnimal.makeSound() someAnimal.makeSound = fun () { println("Woof!") } someAnimal.makeSound() } assertEquals(listOf("Meow!", "Woof!"), output) }
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд░рдгрдиреАрддрд┐ рдкреИрдЯрд░реНрди рд╣реИ, рдФрд░ рдЖрдк рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ (рд╣реИрд▓реЛ, JS!) рдирд╣реАрдВ рдмрджрд▓ рд╕рдХрддреЗред
// Won't compile! someAnimal.makeSound = fun (message : String) { println("$message") }
рд╕рднреА рдХреЛрдб рдореЗрд░реЗ GitHub рдкреЗрдЬ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред
рдФрд░ рдпрджрд┐ рдЖрдк рдХреЛрдЯрд▓рд┐рди рдФрд░ рдЗрд╕рдХреЗ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рдорд╣рд╛рди рдкреБрд╕реНрддрдХ рд╣реИ, "рдХреЛрдЯрд▓рд┐рди рдЗрди рдПрдХреНрд╢рди" ред рдЖрдк рдЗрд╕реЗ рдкрд╕рдВрдж рдХрд░реЗрдВрдЧреЗ рднрд▓реЗ рд╣реА рдЖрдк рдирд┐рдХрдЯ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЗрд╕ рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рди рдХрд░реЗрдВ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИ)ред