This commit is contained in:
Alexander Nozik 2021-04-16 14:23:07 +03:00
parent 6631dba59b
commit 868cbc0f50
11 changed files with 173 additions and 5 deletions

View File

@ -1,5 +1,5 @@
plugins {
kotlin("jvm") version "1.4.31"
kotlin("jvm") version "1.4.32"
}
group = "ru.mipt.npm"

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -0,0 +1,34 @@
package lesson4
class Bad{
val value: Int
init {
value = requestValue()
}
private fun requestValue(): Int = TODO()
}
//Factory functions are preferred to the initialization logic
class Good internal constructor(val value: Int){
init {
//Initialization block is there to check arguments
require(value >= 0)
}
companion object
}
private fun requestValue(): Int = TODO()
// This is the factory-function
fun Good() = Good(requestValue())
// additional constructor-like builders could be added to the companion
@OptIn(ExperimentalUnsignedTypes::class)
fun Good.Companion.build(value: UInt) = Good(value.toInt())

View File

@ -0,0 +1,18 @@
package lesson4
import kotlin.random.Random
//TODO move to beginning of the course
fun main() {
val b = Random.nextBoolean()
// assign value to an expression
val a = if (b) 0 else 1
//Use Try/catch as an exception
val result = try {
"22a".toInt()
} catch (e: NumberFormatException) {
null //Strongly discouraged in performance-critical code
}
}

View File

@ -0,0 +1,11 @@
package lesson4
@OptIn(ExperimentalStdlibApi::class)
fun main() {
//Consume mutating lambda
val list = buildList {
repeat(10){
add(it)
}
}
}

View File

@ -0,0 +1,12 @@
package lesson4
import java.nio.file.Files
import java.nio.file.Paths
fun main() {
val stream = Files.newInputStream(Paths.get("/some/file.txt"))
// The resource is automatically closed when leaving the scope
stream.buffered().reader().use { reader ->
println(reader.readText())
}
}

View File

@ -0,0 +1,24 @@
package lesson4
interface Factory<T : Any> {
fun build(str: String): T
}
class IntContainer(val arg: Int) {
companion object : Factory<IntContainer> {
override fun build(str: String) = IntContainer(str.toInt())
}
}
class DoubleContainer(val arg: Double) {
companion object : Factory<DoubleContainer> {
override fun build(str: String) = DoubleContainer(str.toDouble())
}
}
fun <T : Any> buildContainer(str: String, factory: Factory<T>): T = factory.build(str)
fun main() {
buildContainer("22", IntContainer)
}

View File

@ -0,0 +1,17 @@
package lesson4
class ClassWithALazyProperty{
//Use lazy delegate for something that should be calculated ones on first call
val lazyValue by lazy {
//Do dome heavy logic here
}
}
//Using other delegates
fun main() {
val map = mapOf("a" to 1, "b" to 2)
val a by map
println(a)
}

View File

@ -0,0 +1,36 @@
package lesson4
/**
* The demonstration of use of inline [forEach] function with non-local return
*/
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return // non-local return directly to the caller of foo()
print(it)
}
println("this point is unreachable")
}
/**
* Definition of inline function
*/
inline fun List<Int>.forEachOdd(block: (Int) -> Unit) = forEach {
if (it % 2 == 1) block(it)
}
/**
* Using inline function for type reification during the compile time
*/
inline fun <reified T: Any> List<T>.prettyPrint() = forEach {
when (T::class) {
Double::class -> println("Double: ${it as Double}")
Int::class -> println("Int: ${it as Int}")
else -> it.toString()
}
}
/**
* **WARNING** inline functions are an advanced feature and should be used only for reification or non-local return
* NOT for optimization.
*/

View File

@ -0,0 +1,16 @@
package lesson4
/**
* Values are boxed. Each call is indirect
*/
val list: List<Double> = List(20){it.toDouble()}
/**
* Still boxed
*/
val genericArray: Array<Double> = Array(20){it.toDouble()}
/**
* Non-boxed
*/
val specializedArray: DoubleArray = DoubleArray(20){it.toDouble()}