Kotlin ?

Pourquoi Kotlin ?

Environnement

Où l'utiliser ?

  • Développement mobile
  • Développement back
  • Développement front

1 langage

2 paradigmes

Quelques bases

Inférence de type

var myVariable : String = "ma première chaine"

var myVariable2 = "ma seconde chaine"

Typage fort

fun add(param1: Int, param2: Int ) : Int
{
    return param1 + param2
}

Null Safe

class HelloWorld {

    fun displayNullableMessage(message: String?) {
        print(message)
    }

    fun displayMessage(message: String) {
        print(message)
    }
}

fun main(args: Array<String>) {

    val service = HelloWorld()
    val s : String? = null

    service.displayMessage(s) //does not compile
    if( s != null ){
        service.displayMessage(s) //compile
    }
    service.displayNullableMessage(null)

}

Immutabilité

var myVariable : String = "ma variable"
myVariable = "ma variable mis à jour"

val myConst = "ma constante"
myConst = "ma constante mise à jour" // does not compile

Concis

fun add(a: Int, b: Int): Int {
    return a + b
}
fun add(a: Int, b: Int) = a + b
fun displaySize(x: Any) {
    if (x is String) {
        print(x.length)
    } else{
        print("Not a String")
    }
}
fun getCity(p: Person?): String {
    return p?.address?.city
}
fun getCityWithNPE(p: Person?): String {
    return p!!.address!!.city
}
fun getAddress(p: Person?): Address {
    return p?.address ?: Address()
}

Null Safe

Elvis Operator

Pour les nostalgiques

listOf("Tintin", "Asterix", "Milou")
    .map { it -> it.toUpperCase() }
    .forEach { it -> println(it) }
listOf("Tintin", "Asterix", "Milou")
    .map { it.toUpperCase() }
    .forEach { println(it) }

Un peu de fonctionnel

Utilisation avec Spring

<build>
    <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
            <configuration>
                <compilerPlugins>
                    <plugin>all-open</plugin>
                    <plugin>spring</plugin>
                    <plugin>jpa</plugin>
                </compilerPlugins>
                <pluginOptions>
                    <option>all-open:annotation=com.zenika.SimpleAnnotation</option>
                    <option>all-open:annotation=com.zenika.ComplexAnnotation</option>
                </pluginOptions>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.jetbrains.kotlin</groupId>
                    <artifactId>kotlin-maven-allopen</artifactId>
                    <version>${kotlin.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
@SpringBootApplication
class MatinaleSpringApplication

fun main(args: Array<String>) {
    runApplication<MatinaleSpringApplication>(*args)
}
@RestController
class SampleController(val sampleService: SampleService?) {

    @GetMapping("/hello/{name}")
    fun hello(@PathVariable name: String): String {
        sampleService?.greet()

        return "Hello $name"
    }
}
interface CompanyRepository : CrudRepository<Company, UUID> {
    
    fun findAllByOrderByNameAsc(): Iterable<Company>
}
@Entity
@Table(name = "companies")
data class Company(@Id var  id:  UUID = UUID.randomUUID(), 
                    var name: String = "",
                    val state: Boolean = true)
beans {
  bean<UserHandler>()
  bean<Routes>()
  bean<WebHandler>("webHandler") {
    RouterFunctions.toWebHandler(
      ref<Routes>().router(),
      HandlerStrategies.builder().viewResolver(ref()).build()
    )
  }
  profile("foo") {
    bean<Foo>()
  }
}
router {
  accept(TEXT_HTML).nest {
    GET("/") { ok().render("index") }
    GET("/sse") { ok().render("sse") }
  }
  "/api".nest {
    accept(TEXT_EVENT_STREAM).nest {
      GET("/users", userHandler::stream)
    }		
  }
  resources("/**", ClassPathResource("static/"))
}

Spring-kotlin-functional

Differents runtimes

  • Java
  • Javascript
  • Native (LLVM)
  • Android

Web Assembly

By erwann thebault

Web Assembly

  • 351