Kotlin print(), println(), readLine(), Scanner, REPL

Hoje vamos aprender como usar as funções de impressão em Kotlin e como obter e analisar a entrada do usuário pelo console. Além disso, vamos explorar o REPL do Kotlin.

Funções de Impressão em Kotlin

Para exibir algo na tela, são usados os seguintes dois métodos:

  • print()
  • println()

A instrução print imprime tudo o que está dentro dela na tela. A instrução println adiciona uma nova linha ao final da saída. As instruções de impressão chamam internamente System.out.print. O código a seguir mostra as instruções de impressão em ação:

fun main(args: Array<String>) {
var x = 5
print(x++)
println("Hello World")
print("Do dinasours still exist?\n")
print(false)
print("\nx is $x.")
println(" x Got Updated!!")
print("Is x equal to 6?: ${x == 6}\n")    
}

Para imprimir uma variável dentro da instrução de impressão, precisamos usar o símbolo do dólar ($) seguido do nome da var/val dentro de uma string literal entre aspas duplas. Para imprimir o resultado de uma expressão, usamos ${ //a expressão vai aqui }. A saída quando o código acima é executado no Kotlin Online Compiler é mostrada abaixo.

Escapar literais e expressões

Para escapar do símbolo do dólar e, digamos, tratar ${expressão} apenas como uma string em vez de calculá-la, podemos escapá-la.

fun main(args: Array<String>) {
val y = "\${2 == 5}"
println("y = ${y}")       
println("Do we use $ to get variables in Python or PHP? Example: ${'$'}x and ${'$'}y")
val z = 5
var str = "$z"
println("z is $str")
str = "\$z"
println("str is $str")
}

Observe que um simples $ sem qualquer expressão/variável definida implicitamente o escapa e o trata apenas como parte da string.

Valores de função de impressão

fun sumOfTwo(a: Int, b: Int) : Int{
    return a + b
}

fun main(args: Array<String>) {
val a = 2
val b = 3
println("Value of ${'$'}a and ${'$'}b is : ${sumOfTwo(a,b)}") 
println(println("Printing Value of ${'$'}a and ${'$'}b is : ${sumOfTwo(a,b)}"))    
}

A saída a seguir é impressa: Nota: Passar um print dentro de outro comporta-se como recursão. O mais interno é impresso primeiro. A instrução print retorna um Unit (equivalente a void em Java).

Entrada do Usuário Kotlin

Para obter a entrada do usuário, os seguintes dois métodos podem ser usados:

Nota: A entrada do usuário requer uma ferramenta de linha de comando. Você pode usar REPL ou IntelliJ. Vamos usar IntelliJ aqui.

Usando readLine()

readLine() retorna o valor do tipo String? para lidar com valores nulos que podem ocorrer ao ler o final do arquivo, etc. O código a seguir mostra um exemplo usando readLine().

fun main(args: Array<String>) {
    println("Enter your name:")
    var name = readLine()
    print("Length is ${name?.length}")
}

Como você pode ver, precisamos desembrulhar o tipo nullable para usar as funções do tipo String na propriedade. Use !! para converter forçadamente o String? em String, apenas quando tiver absoluta certeza de que o valor não será nulo. Caso contrário, ocorrerá uma falha. Convertendo a entrada para um Inteiro Para converter a String de entrada em um Int, fazemos o seguinte:

fun main(args: Array<String>) {
var number = readLine()
try {
        println("Number multiply by 5 is ${number?.toInt()?.times(5)}")
    } catch (ex: NumberFormatException) {
        println("Number not valid")
    }
}

Novamente, usamos o operador ?. para converter o tipo nullable primeiro em um Int usando toInt(). Em seguida, multiplicamos por 5. Lendo Entrada Continuamente Podemos usar o loop do-while para ler a entrada continuamente, conforme mostrado abaixo.

    do {
        line = readLine()

        if (line == "quit") {
            println("Closing Program")
            break
        }

        println("Echo $line")

    } while (true)
}

O resultado do código acima na Linha de Comando do IntelliJ é dado abaixo.

Lendo Múltiplos Valores usando o operador split

Podemos ler múltiplos valores separados por delimitadores e salvá-los em forma de tupla, como mostrado abaixo.

fun readIntegers(separator: Char = ',')
        = readLine()!!.split(separator).map(String::toInt)

fun main(args: Array<String>) {
    println("Enter your values:")
    try {
        val (a, b, c) = readLine()!!.split(' ')
        println("Values are $a $b and $c")
    } catch (ex: IndexOutOfBoundsException) {
        println("Invalid. Missing values")
    }

    try {
        val (x, y, z) = readIntegers()
        println("x is $x y is $y z is $z")
    } catch (ex: IndexOutOfBoundsException) {
        println("Invalid. Missing values")
    }
    catch (ex: NumberFormatException) {
        println("Number not valid")
    }

}

A função split recebe o caractere que será o delimitador. A função readIntegers() utiliza um mapa em um split para converter cada valor em um Inteiro. Se você inserir valores menores do que os especificados na tupla, ocorrerá um IndexOutOfBoundsException. Utilizamos try-catch em ambas as entradas. A saída parece com isso: Alternativamente, em vez de tuplas, também podemos usar uma lista, como mostrado abaixo.

val ints: List<String>? = readLine()?.split("|".toRegex())
println(ints)

Classe Kotlin Scanner

Para receber entradas, podemos usar Scanner(System.`in`), que recebe entradas do teclado de entrada padrão. O código a seguir demonstra o mesmo:

fun main(args: Array) {
    val reader = Scanner(System.`in`)
    print("Enter a number: ")

    // nextInt() lê o próximo inteiro. next() lê a String
    var integer:Int = reader.nextInt()

    println("You entered: $integer")

reader.nextInt() lê o próximo inteiro. reader.next() lê a próxima String. reader.nextFloat() lê o próximo float e assim por diante. reader.nextLine() passa o Scanner para a próxima linha e também limpa o buffer. O código a seguir demonstra a leitura de diferentes tipos de entradas dentro de uma declaração de impressão.

import java.util.*

fun main(args: Array) {

    val reader = Scanner(System.`in`)
    print("Enter a number: ")

    try {
        var integer: Int = reader.nextInt()
        println("You entered: $integer")
    } catch (ex: InputMismatchException) {
        println("Enter valid number")
    }
    enterValues(reader)
    // mova o scanner para a próxima linha, caso contrário, a entrada em buffer será lida para a próxima aqui apenas.
    reader.nextLine()
    enterValues(reader)
}

fun enterValues(reader: Scanner) {
    println("Enter a float/boolean :")
    try {
        print("Values: ${reader.nextFloat()}, ${reader.nextBoolean()}")
    } catch (ex: InputMismatchException) {
        println("First value should be a float, second should be a boolean. (Separated by enter key)")
    }
}

A exceção InputMismatch é lançada quando a entrada é de um tipo diferente do solicitado. A saída é mostrada abaixo.

Kotlin REPL

O REPL, também conhecido como Read-Eval-Print-Loop, é usado para executar uma parte do código em um shell interativo diretamente. Podemos fazer isso em nosso terminal/linha de comando iniciando o compilador Kotlin.

Instalando o Compilador de Linha de Comando

Podemos instalar o compilador de linha de comando no Mac/Windows/Ubuntu conforme demonstrado aqui. Tipicamente, em um Mac, podemos usar o HomeBrew no nosso terminal para instalar o compilador Kotlin.

brew update
brew install kotlin

Assim que estiver feito, inicie o REPL digitando kotlinc no seu terminal/cmd. Segue abaixo meu primeiro código no REPL. Isso é tudo para as funções de impressão do Kotlin e uma rápida introdução ao Kotlin REPL.

Source:
https://www.digitalocean.com/community/tutorials/kotlin-print-println-readline-scanner-repl