Kotlin is made by JetBrains (the same as that did IntelliJ the IDE).
See their website here:
Check out some real examples at Sylhare/Kotlin!
Project Structure
Assuming you know how to work with Gradle.
You need to create the gradle file build.gradle.kts then add dependencies and configurations.
An example with Kotlin dsl with gradle 4.8.
But you might want to take the latest Gradle version available, you’ll have up to date and better information.
For gradle to pick up the source and test files, you will need to organise your folders like:
└── src
├── main
│ └── kotlin
│ └── package
└── test
└── kotlin
└── package
Kotlin Specifics
Miscellaneous
- Use
`(back tick) to define method’s name with space:
@Test
fun `valid parameters` { ... }
- Overload Objects to generates new ones easily:
val Number.teaspoons get() = Quantity(this, Unit.teaspoon)
So then you can use it this way:
Quantity(1.5, Unit.teasponn)
1.5.teaspoons
- Before a recursion, ask yourself these questions:
- What is the original question?
- What is the recursive question?
- What are the Terminal condition? (when the recursive stops)
Handling null
- The
?is used in Kotlin to handle null:
// The Rectangle? makes the function returns Rectangle or null
fun mayReturnRectangleOrNull() : Rectangle? { ... }
// With "?." the .rectangleMethod() will only occur when mayReturnRectangleOrNull() returns a rectangle
mayReturnRectangleOrNull()?.rectangleMethod()
// Elvis ?: to have another value if the preceeding one return null
val somethingNotNull = emptyRectangle()
return mayReturnRectangleOrNull() ?: somethingNotNull
- The
!!to force the function to operate even though it can be null:
return if (list.isEmpty) -1 else list.min()!! //list can be null, without !! it would complain, but can still return null
- Using the
this@Classinside of alist.apply { this.prepend(this@Class) }, you are calling thethisof the class (sothis@Classto differentiate from the otherthis(element of the list that you apply to).
Keywords
Anyfor any typeinit {}to initiate the values at the creation of the classoverrideat the beginning of the function to override it:
override fun equals(other: Any?) { ... }
operatorto override an operator function. Here an example with the comparison operator (>,<, …)
operator fun compareTo(other: Probability) { ... }
infixfunction are function where you can omit the.:
infix fun isCompatibleWith(other: Unit): Boolean { ... }
// calling the function using the infix notation
unit isCompatibleWith otherUnit
// is the same as
unit.isCompatibleWith(otherUnit)
typealiasis used to define a name for a function signature (hence alias) usually used to simplify simple functions into a type:
internal typealias CostStrategy = (Double) -> Double
- For Properties unless they are private, a getter / setter is automatically “build” but you can custom its behaviour through:
// To custom the Getter / Setter of a field
private var field: String = "field"
var proxyField: String
get() = field
set(value) { field = value }
// Public Getter and private Setter
var abc: String = ""; private set
Operation on lists
flatMaptransforms a list of list of stuff into a simple list of stuff
list.flatMap { List<List<Path>> } // returns List<Path>
-
onEachis the same aslist.map{ this.apply { ... } } -
sumByDoubleis the same aslist.map{}.sum{}