1
1
Fork 0

Regenerated samples

This commit is contained in:
Svetlana Isakova 2020-11-17 20:00:10 +01:00
parent f5ea6e73af
commit a3d7a6660a
75 changed files with 617 additions and 446 deletions

View File

@ -1,25 +1,28 @@
// Interoperability/BigFibonacci.kt
package interop
import atomictest.eq
import bigint.*
import java.math.BigInteger
import java.math.BigInteger.ONE
import java.math.BigInteger.ZERO
fun fibonacci(n: Int): BigInt {
fun fibonacci(n: Int): BigInteger {
tailrec fun fibonacci(
n: Int,
current: BigInt,
next: BigInt
): BigInt {
current: BigInteger,
next: BigInteger
): BigInteger {
if (n == 0) return current
return fibonacci(
n - 1, next, current + next)
n - 1, next, current + next) // [1]
}
return fibonacci(n, zero, one)
return fibonacci(n, ZERO, ONE)
}
fun main() {
(0..7).map { fibonacci(it) } eq
"[0, 1, 1, 2, 3, 5, 8, 13]"
fibonacci(22) eq 17711.big
fibonacci(22) eq 17711.toBigInteger()
fibonacci(150) eq
"9969216677189303386214405760200".big
"9969216677189303386214405760200"
.toBigInteger()
}

View File

@ -1,14 +1,13 @@
// Interoperability/BigInt.kt
package bigint
package biginteger
import java.math.BigInteger
typealias BigInt = BigInteger
fun Int.toBigInteger(): BigInteger =
BigInteger.valueOf(this.toLong())
val Int.big: BigInt
get() = BigInt.valueOf(toLong())
fun String.toBigInteger(): BigInteger =
BigInteger(this)
val String.big: BigInt
get() = BigInt(this)
val zero = BigInt.ZERO
val one = BigInt.ONE
operator fun BigInteger.plus(
other: BigInteger
): BigInteger = this.add(other)

View File

@ -2,8 +2,8 @@
package Interoperability;
import java.io.Serializable;
public class
Chameleon implements Serializable {
public class Chameleon
implements Serializable {
private int size;
private String color;
public int getSize() {

View File

@ -8,7 +8,7 @@ public class JavaChecked {
// Build path to current source file, based
// on directory where Gradle is invoked:
static Path thisFile = Paths.get(
"DataFiles", "file_real.txt");
"DataFiles", "file_wubba.txt");
public static void main(String[] args) {
BufferedReader source = null;
try {

View File

@ -0,0 +1,13 @@
// Interoperability/JavaWrapper.java
package Interoperability;
import java.util.List;
public class JavaWrapper {
public static void main(String[] args) {
// Primitive type
int i = 10;
// Wrapper types
Integer iOrNull = null;
List<Integer> list = List.of(1, 2, 3);
}
}

View File

@ -0,0 +1,25 @@
// Interoperability/UseDataClass.java
package Interoperability;
import java.util.HashMap;
import static atomictest.AtomicTestKt.eq;
public class UseDataClass {
public static void main(String[] args) {
Muppet m = new Muppet("Ernie", 6);
int ageErnie = m.getAge();
m.setName("Bert");
m.setAge(7);
eq(ageErnie < m.getAge(), true);
eq(m, "Muppet(name=Bert, age=7)");
// Call copy() from the data class:
Muppet mc = m.copy("???", 5);
eq(mc, "Muppet(name=???, age=5)");
HashMap<Muppet, String> hm =
new HashMap<>();
// Muppets work as hash keys:
hm.put(m, "Happy Muppet");
eq(hm.get(m), "Happy Muppet");
}
}

View File

@ -1,24 +0,0 @@
// Interoperability/UsingDataClass.java
package Interoperability;
import java.util.HashMap;
import static atomictest.AtomicTestKt.eq;
public class UsingDataClass {
public static void main(String[] args) {
Data d = new Data("Alice", 22);
String name = d.getName();
d.setName("Bob");
int age = d.getAge();
d.setAge(age + 1);
// toString():
eq(d, "Data(name=Bob, age=23)");
HashMap<Data, Integer> hm =
new HashMap<>();
hm.put(d, 47);
// Data objects work as hash keys:
eq((double)hm.get(d), (double)47);
// Call copy() from the Data class:
Data d2 = d.copy("Sam", 24);
eq(d2, "Data(name=Sam, age=24)");
}
}

View File

@ -3,7 +3,7 @@ import atomictest.eq
import java.io.File
fun main() {
File("DataFiles/file_real.txt")
File("DataFiles/file_wubba.txt")
.readLines()[0] eq
"wubba lubba dub dub"
}

View File

@ -1,7 +1,7 @@
// Interoperability/KotlinDataClass.kt
package Interoperability
data class Data(
data class Muppet(
var name: String,
var age: Int
)

View File

@ -0,0 +1,10 @@
// Interoperability/KotlinWrapper.kt
package interop
fun main() {
// Generates a primitive int:
val i = 10
// Generates wrapper types:
val iOrNull: Int? = null
val list: List<Int> = listOf(1, 2, 3)
}

View File

@ -14,7 +14,7 @@ files:
visible: true
- name: src/KotlinDataClass.kt
visible: true
- name: src/Interoperability/UsingDataClass.java
- name: src/Interoperability/UseDataClass.java
visible: true
- name: src/TopLevelFunction.kt
visible: true
@ -58,3 +58,7 @@ files:
visible: true
- name: src/ReadOnlyCollections.kt
visible: true
- name: src/Interoperability/JavaWrapper.java
visible: true
- name: src/KotlinWrapper.kt
visible: true

View File

@ -1 +0,0 @@
wubba lubba dub dub

View File

@ -1,9 +1,7 @@
## Maps (#3)
If you commonly select elements from a `List` using keys, it makes sense to
optimize by using a `Map` instead of a `List`. A `Map` finds an element in
constant time. With a `List`, in the worst case you must iterate over every
element.
optimize by using a `Map` instead of a `List`.
Change the internal implementation of the `Cage` class to store elements in a
`Map` rather than a `List`. To get an element use the `getValue()` member

View File

@ -1,6 +1,6 @@
## Summary 2 (#3)
Create a `FixedHolder` class with a constructor parameter that sets the
Create a `FixedSizeHolder` class with a constructor parameter that sets the
maximum number of `Any` objects that can be held. Add read-only `size` and
`full` properties. If the user calls `add()` when it's `full`, throw an
`IllegalStateException`.

View File

@ -11,9 +11,9 @@ example, `IV` contains two digits) and store the maximum value found so far. If
the next Roman digit is greater than or equal to the current maximum value, add
it to the result. If it's less than the maximum, subtract it instead. For
example, to convert `XLIV = 44`, iterate over `VILX` which is the reverse of
`XLIV`. You add `V`(`5`) and `L`(`50`), but subtract `1`(`I`) because it's less
than the current maximum `V`, and subtract `10`(`X`) because it's less than the
updated maximum `X`:
`XLIV`. You add `5`(`V`) and subtract `1`(`I`) because it's less than the
current maximum `5`(`V`), then and `50`(`L`) and subtract `10`(`X`) because it's
less than the updated maximum `10`(`X`):
| numeral | current maximum | action |
| ------- |-----------------|--------|

View File

@ -2,18 +2,13 @@
package extensionlambdas
import atomictest.eq
val divideBy = fun Int.(d: Int): Boolean {
return this % d == 0
}
fun exec(
arg1: Int, arg2: Int,
f: Int.(Int) -> Boolean
arg1: Int, arg2: Int,
f: Int.(Int) -> Boolean
) = arg1.f(arg2)
fun main() {
10.divideBy(2) eq true
10.divideBy(3) eq false
exec(10, 2, divideBy) eq true
exec(10, 3, divideBy) eq false
exec(10, 2, fun Int.(d: Int): Boolean {
return this % d == 0
}) eq true
}

View File

@ -13,7 +13,7 @@ fun lambdaUnitReturn () {
"So it can be anything ..."
}
unitReturn { 1 } // ... of any type ...
unitReturn { } // ... or nothing
unitReturn { } // ... or nothing
nonUnitReturn {
"Must return the proper type"
}

View File

@ -14,6 +14,10 @@ private fun clean() = buildString {
('a'..'z').forEach { append(it) }
}
private fun cleaner() =
"ABCs: " + ('a'..'z').fold("", String::plus)
fun main() {
messy() eq clean()
clean() eq cleaner()
}

View File

@ -2,6 +2,14 @@
package extensionlambdas
import atomictest.eq
fun String.transform1(
n: Int, lambda: (String, Int) -> String
) = lambda(this, n)
fun String.transform2(
n: Int, lambda: String.(Int) -> String
) = lambda(this, n)
val duplicate: String.(Int) -> String = {
repeat(it)
}
@ -12,14 +20,6 @@ val alternate: String.(Int) -> String = {
.joinToString("")
}
fun String.transform1(
n: Int, lambda: (String, Int) -> String
) = lambda(this, n)
fun String.transform2(
n: Int, lambda: String.(Int) -> String
) = lambda(this, n)
fun main() {
"hello".transform1(5, duplicate)
.transform2(3, alternate) eq "hleolhleo"

View File

@ -1,76 +0,0 @@
// OperatorOverloading/AllOperators.kt
package operatoroverloading
class C {
// equals() cannot be an extension
// function and must be defined specially:
override operator
fun equals(other: Any?) = true
}
// Unary operators:
operator fun C.unaryPlus() = this
operator fun C.unaryMinus() = this
operator fun C.not() = this
// Increment/decrement:
operator fun C.inc() = this
operator fun C.dec() = this
// Binary operators:
operator fun C.plus(rv: C) = rv
operator fun C.minus(rv: C) = rv
operator fun C.times(rv: C) = rv
operator fun C.div(rv: C) = rv
operator fun C.rem(rv: C) = rv
operator fun C.rangeTo(rv: C) = rv
// 'In' operator:
operator fun C.contains(rv: C) = true
// Indexed access:
operator fun C.get(i: Int) = this
operator fun C.set(i: Int, c: C) = this
// Augmented assignment:
operator fun C.plusAssign(rv: C) = Unit
operator fun C.minusAssign(rv: C) = Unit
operator fun C.timesAssign(rv: C) = Unit
operator fun C.divAssign(rv: C) = Unit
operator fun C.remAssign(rv: C) = Unit
// Comparison, must return Int:
operator fun C.compareTo(rv: C) = 1
fun main() {
val c = C()
+c // unaryPlus()
-c // unaryMinus()
!c // not()
var cc = C()
cc++ // inc() (needs var)
cc-- // dec() (needs var)
c + c // plus()
c - c // minus()
c * c // times()
c / c // div()
c % c // rem()
c..c // rangeTo()
c in c // contains()
c !in c // contains()
c[2] // get()
c[2] = c // set()
c += c // plusAssign()
c -= c // minusAssign()
c *= c // timesAssign()
c /= c // divAssign()
c %= c // remAssign()
// equals():
c == c
c != c
// compareTo():
c < c
c > c
c <= c
c >= c
}

View File

@ -0,0 +1,62 @@
// OperatorOverloading/ArithmeticOperators.kt
package operatoroverloading
import atomictest.eq
// Unary operators:
operator fun E.unaryPlus() = E(v)
operator fun E.unaryMinus() = E(-v)
operator fun E.not() = this
// Increment/decrement:
operator fun E.inc() = E(v + 1)
operator fun E.dec() = E(v - 1)
fun unary(a: E) {
+a // unaryPlus()
-a // unaryMinus()
!a // not()
var b = a
b++ // inc() (must be var)
b-- // dec() (must be var)
}
// Binary operators:
operator fun E.plus(e: E) = E(v + e.v)
operator fun E.minus(e: E) = E(v - e.v)
operator fun E.times(e: E) = E(v * e.v)
operator fun E.div(e: E) = E(v % e.v)
operator fun E.rem(e: E) = E(v / e.v)
fun binary(a: E, b: E) {
a + b // a.plus(b)
a - b // a.minus(b)
a * b // a.times(b)
a / b // a.div(b)
a % b // a.rem(b)
}
// Augmented assignment:
operator fun E.plusAssign(e: E) { v += e.v }
operator fun E.minusAssign(e: E) { v - e.v }
operator fun E.timesAssign(e: E) { v *= e.v }
operator fun E.divAssign(e: E) { v /= e.v }
operator fun E.remAssign(e: E) { v %= e.v }
fun assignment(a: E, b: E) {
a += b // a.plusAssign(b)
a -= b // a.minusAssign(b)
a *= b // a.timesAssign(b)
a /= b // a.divAssign(b)
a %= b // a.remAssign(b)
}
fun main() {
val a = E(2)
val b = E(3)
a + b eq E(5)
a * b eq E(6)
val x = E(1)
x += b * b
x eq E(10)
}

View File

@ -0,0 +1,15 @@
// OperatorOverloading/Comparison.kt
package operatoroverloading
import atomictest.eq
operator fun E.compareTo(e: E): Int =
v.compareTo(e.v)
fun main() {
val a = E(2)
val b = E(3)
(a < b) eq true // a.compareTo(b) < 0
(a > b) eq false // a.compareTo(b) > 0
(a <= b) eq true // a.compareTo(b) <= 0
(a >= b) eq false // a.compareTo(b) >= 0
}

View File

@ -0,0 +1,12 @@
// OperatorOverloading/ConfusingPrecedence.kt
package operatoroverloading
import atomictest.eq
fun main() {
val x: Int? = 1
val y: Int = 2
val sum = x ?: 0 + y
sum eq 1
(x ?: 0) + y eq 3 // [1]
x ?: (0 + y) eq 1 // [2]
}

View File

@ -0,0 +1,24 @@
// OperatorOverloading/ContainerAccess.kt
package operatoroverloading
import atomictest.eq
data class C(val c: MutableList<Int>) {
override fun toString() = "C($c)"
}
operator fun C.contains(e: E) = e.v in c
operator fun C.get(i: Int): E = E(c[i])
operator fun C.set(i: Int, e: E) {
c[i] = e.v
}
fun main() {
val c = C(mutableListOf(2, 3))
(E(2) in c) eq true // c.contains(E(2))
(E(4) in c) eq false // c.contains(E(4))
c[1] eq E(3) // c.get(1)
c[1] = E(4) // c.set(2, E(4))
c eq C(mutableListOf(2, 4))
}

View File

@ -0,0 +1,19 @@
// OperatorOverloading/DefaultEquality.kt
package operatoroverloading
import atomictest.eq
class A(val i: Int)
data class D(val i: Int)
fun main() {
// Normal class:
val a = A(1)
val b = A(1)
val c = a
(a == b) eq false
(a == c) eq true
// Data class:
val d = D(1)
val e = D(1)
(d == e) eq true
}

View File

@ -0,0 +1,22 @@
// OperatorOverloading/DefiningEquality.kt
package operatoroverloading
import atomictest.eq
class E(var v: Int) {
override fun equals(other: Any?) = when {
this === other -> true // [1]
other !is E -> false // [2]
else -> v == other.v // [3]
}
override fun hashCode(): Int = v
override fun toString() = "E($v)"
}
fun main() {
val a = E(1)
val b = E(2)
(a == b) eq false // a.equals(b)
(a != b) eq true // !a.equals(b)
// Reference equality:
(E(1) === E(1)) eq false
}

View File

@ -0,0 +1,9 @@
// OperatorOverloading/DifferentTypes.kt
package operatoroverloading
import atomictest.eq
operator fun E.plus(i: Int) = E(v + i)
fun main() {
E(1) + 10 eq E(11)
}

View File

@ -0,0 +1,24 @@
// OperatorOverloading/EqualsForNullable.kt
package operatoroverloading
import atomictest.eq
fun equalsWithIf(a: E?, b: E?) =
if (a === null)
b === null
else
a == b
fun equalsWithElvis(a: E?, b: E?) =
a?.equals(b) ?: (b === null)
fun main() {
val x: E? = null
val y = E(0)
val z: E? = null
(x == y) eq false
(x == z) eq true
equalsWithIf(x, y) eq false
equalsWithIf(x, z) eq true
equalsWithElvis(x, y) eq false
equalsWithElvis(x, z) eq true
}

View File

@ -0,0 +1,21 @@
// OperatorOverloading/Ranges.kt
package operatoroverloading
import atomictest.eq
data class R(val r: IntRange) { // Range
override fun toString() = "R($r)"
}
operator fun E.rangeTo(e: E) = R(v..e.v)
operator fun R.contains(e: E): Boolean =
e.v in r
fun main() {
val a = E(2)
val b = E(3)
val r = a..b // a.rangeTo(b)
(a in r) eq true // r.contains(a)
(a !in r) eq false // !r.contains(a)
r eq R(2..3)
}

View File

@ -6,8 +6,6 @@ files:
visible: true
- name: src/Molecule.kt
visible: true
- name: src/AllOperators.kt
visible: true
- name: src/Invoke.kt
visible: true
- name: src/StringInvoke.kt
@ -16,3 +14,21 @@ files:
visible: true
- name: src/Swearing.kt
visible: true
- name: src/DifferentTypes.kt
visible: true
- name: src/Ranges.kt
visible: true
- name: src/ContainerAccess.kt
visible: true
- name: src/DefiningEquality.kt
visible: true
- name: src/ArithmeticOperators.kt
visible: true
- name: src/ConfusingPrecedence.kt
visible: true
- name: src/EqualsForNullable.kt
visible: true
- name: src/Comparison.kt
visible: true
- name: src/DefaultEquality.kt
visible: true

View File

@ -1,9 +1,9 @@
// PropertyDelegation/CarService.kt
// DelegationTools/CarService.kt
package propertydelegation
import atomictest.eq
class Driver(
val map: MutableMap<String, Any?>
map: MutableMap<String, Any?>
) {
var name: String by map
var age: Int by map
@ -20,7 +20,7 @@ fun main() {
"available" to false,
"coord" to Pair(111.93, 1231.12)
)
val driver = Driver(info);
val driver = Driver(info)
driver.available eq false
driver.available = true
info eq "{name=Bruno Fiat, age=22, " +

View File

@ -1,75 +0,0 @@
// DelegationTools/DelegateProvider.kt
package delegationtools
import kotlin.reflect.KProperty
import atomictest.*
class Delegate<T>(private var value: T) {
operator fun getValue(
thisRef: Any?,
property: KProperty<*>
): T {
trace("getValue: $value")
return value
}
operator fun setValue(
thisRef: Any?,
property: KProperty<*>,
newValue: T
) {
trace("setValue: $newValue")
value = newValue
}
}
class DelegateProvider<T>(val value: T) {
operator fun provideDelegate(
thisRef: Any?,
property: KProperty<*>
): Delegate<T> {
trace("providing Delegate($value)")
return Delegate(value)
}
}
fun <T> delegate(value: T):
DelegateProvider<T> {
trace("creating DelegateProvider($value)")
return DelegateProvider(value)
}
fun main() {
var x by delegate(3.14)
trace("x created")
var y by delegate("Hello")
trace("y created")
var z by DelegateProvider(true)
trace("z created")
x eq 3.14
x = 1.62
x eq 1.62
y eq "Hello"
y = "Goodbye"
y eq "Goodbye"
z eq true
z = false
z eq false
trace eq """
creating DelegateProvider(3.14)
providing Delegate(3.14)
x created
creating DelegateProvider(Hello)
providing Delegate(Hello)
y created
providing Delegate(true)
z created
getValue: 3.14
setValue: 1.62
getValue: 1.62
getValue: Hello
setValue: Goodbye
getValue: Goodbye
getValue: true
setValue: false
getValue: false
"""
}

View File

@ -0,0 +1,16 @@
// DelegationTools/MapAccessors.kt
package delegationtools
import kotlin.reflect.KProperty
operator fun MutableMap<String, Any>.getValue(
thisRef: Any?, property: KProperty<*>
): Any? {
return this[property.name]
}
operator fun MutableMap<String, Any>.setValue(
thisRef: Any?, property: KProperty<*>,
value: Any
) {
this[property.name] = value
}

View File

@ -6,5 +6,7 @@ files:
visible: true
- name: src/NeverNull.kt
visible: true
- name: src/DelegateProvider.kt
- name: src/MapAccessors.kt
visible: true
- name: src/CarService.kt
visible: true

View File

@ -1,5 +1,5 @@
// PropertyDelegation/PropDelegationSoln1.kt
package propertyDelegationExercise1
package propertyDelegationToolsExercise1
import atomictest.eq
class Configuration(

View File

@ -3,10 +3,10 @@ files:
- name: src/Task.kt
visible: true
placeholders:
- offset: 103
- offset: 108
length: 141
placeholder_text: class Configuration
- offset: 259
- offset: 264
length: 323
placeholder_text: |-
/*

View File

@ -1,4 +1,4 @@
## Property Delegation (#1)
## Property Delegation Tools (#1)
Convert `Configuration.kt` to use a `Map` instead of a file. The starter code
in `main()` tests your new `Configuration` class.

View File

@ -1,9 +1,9 @@
package propertyDelegationExercise1
package propertyDelegationToolsExercise1
import org.junit.Test
import util.unimplementedTest
class TestPropertyDelegationExercise1 {
class TestPropertyDelegationToolsExercise1 {
@Test fun testSolution() {
unimplementedTest()
}

View File

@ -1,5 +1,5 @@
// DelegationTools/DelegToolsSoln1.kt
package propertyDelegationToolsExercise1
package propertyDelegationToolsExercise2
import kotlin.properties.Delegates
import atomictest.*

View File

@ -1,4 +1,4 @@
## Property Delegation Tools (#1)
## Property Delegation Tools (#2)
The starter code defines a `data class` called `Flag` containing a `Boolean`
called `b` with a default value of `false`. In `main()`, create three `var`s:

View File

@ -1,9 +1,9 @@
package propertyDelegationToolsExercise1
package propertyDelegationToolsExercise2
import org.junit.Test
import util.unimplementedTest
class TestPropertyDelegationToolsExercise1 {
class TestPropertyDelegationToolsExercise2 {
@Test fun testSolution() {
unimplementedTest()
}

View File

@ -1,5 +1,5 @@
// DelegationTools/DelegToolsSoln2.kt
package propertyDelegationToolsExercise2
package propertyDelegationToolsExercise3
import kotlin.properties.Delegates.observable
import kotlin.reflect.KProperty
import atomictest.*

View File

@ -1,4 +1,4 @@
## Property Delegation Tools (#2)
## Property Delegation Tools (#3)
Create a generic function `observe()` that uses `trace()` to capture
`"$propertyName $oldValue to $newValue"` whenever a property changes. Ensure

View File

@ -1,9 +1,9 @@
package propertyDelegationToolsExercise2
package propertyDelegationToolsExercise3
import org.junit.Test
import util.unimplementedTest
class TestPropertyDelegationToolsExercise2 {
class TestPropertyDelegationToolsExercise3 {
@Test fun testSolution() {
unimplementedTest()
}

View File

@ -1,5 +1,5 @@
// DelegationTools/DelegToolsSoln3.kt
package propertyDelegationToolsExercise3
package propertyDelegationToolsExercise4
import atomictest.eq
import kotlin.properties.Delegates

View File

@ -1,4 +1,4 @@
## Property Delegation Tools (#3)
## Property Delegation Tools (#4)
Create a `class PositiveInt(i: Int)` containing a property `var n` such that
any value assigned to `n` can only be greater than zero. The starter code in

View File

@ -1,9 +1,9 @@
package propertyDelegationToolsExercise3
package propertyDelegationToolsExercise4
import org.junit.Test
import util.unimplementedTest
class TestPropertyDelegationToolsExercise3 {
class TestPropertyDelegationToolsExercise4 {
@Test fun testSolution() {
unimplementedTest()
}

View File

@ -18,5 +18,3 @@ files:
visible: true
- name: src/Configuration.kt
visible: true
- name: src/CarService.kt
visible: true

View File

@ -1,5 +1,5 @@
// PropertyDelegation/PropDelegationSoln2.kt
package propertyDelegationExercise2
package propertyDelegationExercise1
import atomictest.eq
import kotlin.reflect.KProperty

View File

@ -1,4 +1,4 @@
## Property Delegation (#2)
## Property Delegation (#1)
Starting with `Add.kt`, add a `setValue()` extension function to `Sum` that
assigns its `value` argument to `a` in `Add` (change `Add` to make this work).

View File

@ -1,9 +1,9 @@
package propertyDelegationExercise2
package propertyDelegationExercise1
import org.junit.Test
import util.unimplementedTest
class TestPropertyDelegationExercise2 {
class TestPropertyDelegationExercise1 {
@Test fun testSolution() {
unimplementedTest()
}

View File

@ -1,5 +1,5 @@
// PropertyDelegation/PropDelegationSoln3.kt
package propertyDelegationExercise3
package propertyDelegationExercise2
import atomictest.eq
import kotlin.reflect.KProperty

View File

@ -1,4 +1,4 @@
## Property Delegation (#3)
## Property Delegation (#2)
Start with:

View File

@ -1,9 +1,9 @@
package propertyDelegationExercise3
package propertyDelegationExercise2
import org.junit.Test
import util.unimplementedTest
class TestPropertyDelegationExercise3 {
class TestPropertyDelegationExercise2 {
@Test fun testSolution() {
unimplementedTest()
}

View File

@ -1,5 +1,5 @@
// PropertyDelegation/PropDelegationSoln4.kt
package propertyDelegationExercise4
package propertyDelegationExercise3
import atomictest.eq
import kotlin.reflect.KProperty

View File

@ -1,4 +1,4 @@
## Property Delegation (#4)
## Property Delegation (#3)
Create a generic class that begins:

View File

@ -1,9 +1,9 @@
package propertyDelegationExercise4
package propertyDelegationExercise3
import org.junit.Test
import util.unimplementedTest
class TestPropertyDelegationExercise4 {
class TestPropertyDelegationExercise3 {
@Test fun testSolution() {
unimplementedTest()
}

View File

@ -0,0 +1,13 @@
// ScopeFunctions/AndNullability.kt
package scopefunctions
import atomictest.eq
import kotlin.random.Random
fun gets(): String? =
if (Random.nextBoolean()) "str!" else null
fun main() {
gets()?.let {
it.removeSuffix("!") + it.length
}?.eq("str4")
}

View File

@ -3,8 +3,9 @@ package scopefunctions
import atomictest.*
data class Blob(val id: Int) : AutoCloseable {
fun show() { trace("Show $id")}
override fun close() = trace("Close $id")
override fun toString() = "Blob($id)"
fun show() { trace("$this")}
override fun close() = trace("Close $this")
}
fun main() {
@ -19,20 +20,20 @@ fun main() {
Blob(9).also { it.show() }.apply { close() }
Blob(10).apply { show() }.use { }
trace eq """
Show 1
Show 2
Show 3
Show 4
Show 5
Show 6
Close 6
Show 7
Close 7
Show 8
Close 8
Show 9
Close 9
Show 10
Close 10
Blob(1)
Blob(2)
Blob(3)
Blob(4)
Blob(5)
Blob(6)
Close Blob(6)
Blob(7)
Close Blob(7)
Blob(8)
Close Blob(8)
Blob(9)
Close Blob(9)
Blob(10)
Close Blob(10)
"""
}

View File

@ -1,64 +0,0 @@
// ScopeFunctions/Differences.kt
package scopefunctions
import atomictest.eq
data class Tag(var n: Int = 0) {
var s: String = ""
fun increment() = ++n
}
fun main() {
// let(): Access object with 'it'
// Returns last expression in lambda
val let1: Int = Tag(1).let {
it.s = "let: ${it.n}"
it.increment()
}
let1 eq 2
// let() with named lambda argument:
val let2: Int = Tag(2).let { tag ->
tag.s = "let: ${tag.n}"
tag.increment()
}
let2 eq 3
// run(): Access object with 'this'
// Returns last expression in lambda
val run1: Int = Tag(3).run {
s = "run: $n"
increment()
}
run1 eq 4
// with(): Access object with 'this'
// Returns last expression in lambda
val with1: Int = with(Tag(4)) {
s = "with: $n"
increment()
}
with1 eq 5
// apply(): Access object with 'this'
// Returns modified object
val apply1: Tag = Tag(5).apply {
s = "apply: $n"
increment()
}
apply1 eq "Tag(n=6)"
// also(): Access object with 'it'
// Returns modified object
val also1: Tag = Tag(6).also {
it.s = "also: ${it.n}"
it.increment()
}
also1 eq "Tag(n=7)"
// also() with named lambda argument:
val also2: Tag = Tag(7).also { tag ->
tag.s = "also: ${tag.n}"
tag.increment()
}
also2 eq "Tag(n=8)"
}

View File

@ -9,7 +9,7 @@ fun display(map: Map<String, Plumbus>) {
val pb1: Plumbus = map["main"]?.let {
it.id += 10
it
} ?: return // [1]
} ?: return
trace(pb1)
val pb2: Plumbus? = map["main"]?.run {

View File

@ -6,23 +6,23 @@ val functions = listOf(
fun(name: String?) {
name
?.takeUnless { it.isBlank() }
?.let { trace("Hi! I am $it") }
?.let { trace("$it in let") }
},
fun(name: String?) {
name
?.takeUnless { it.isBlank() }
?.run { trace("Hi! I am $this") }
?.run { trace("$this in run") }
},
fun(name: String?) {
name
?.takeUnless { it.isBlank() }
?.apply { trace("Hi! I am $this") }
?.apply { trace("$this in apply") }
},
fun(name: String?) {
name
?.takeUnless { it.isBlank() }
?.also { trace("Hi! I am $it") }
}
?.also { trace("$it in also") }
},
)
fun main() {
@ -30,9 +30,9 @@ fun main() {
functions.forEach { it(" ") }
functions.forEach { it("Yumyulack") }
trace eq """
Hi! I am Yumyulack
Hi! I am Yumyulack
Hi! I am Yumyulack
Hi! I am Yumyulack
Yumyulack in let
Yumyulack in run
Yumyulack in apply
Yumyulack in also
"""
}

View File

@ -0,0 +1,34 @@
// ScopeFunctions/Nesting.kt
package scopefunctions
import atomictest.eq
fun nesting(s: String, i: Int): String =
with(s) {
with(i) {
toString()
}
} +
s.let {
i.let {
it.toString()
}
} +
s.run {
i.run {
toString()
}
} +
s.apply {
i.apply {
toString()
}
} +
s.also {
i.also {
it.toString()
}
}
fun main() {
nesting("X", 7) eq "777XX"
}