Can I use ULong as a parameter in function definition in Kotlin?
My code looks like below:
import androidx.compose.ui.graphics.Color
fun EColor(value: ULong) = Color(value)
val Red700 = EColor(0xffdd0d3c)
Then I got an error looks like:
Conversion of signed constants to unsigned ones is prohibited
If I call val Red700 = Color(0xffdd0d3c), then it works fine.
So how come I got this error?
There are unsigned literals in Kotlin. You write them by adding a u or U suffix:
val Red700 = EColor(0xffdd0d3cU)
You can also call toULong:
val Red700 = EColor(0xffdd0d3c.toULong())
Related
example:
fun main(){
var userInput: String?
//userInput = null
userInput = "asbdef"
var inputLength:Int? = userInput!!.length
println("Length of the string is :"+inputLength)
}
Output :
Length of the string is :6
fun main(){
var userInput: String?
userInput = null
//userInput = "asbdef"
var inputLength:Int? = userInput!!.length
println("Length of the string is :"+inputLength)
}
Output :
Unresolved reference: length
I want to know why it gives compile error?
If I just replace (!!) operator with (?) it compiles well but prints output as null.
PS: I'm newbie in Kotlin
The ?. operator short-circuits if the left side evaluates to null. So the result of nullVariable?.length is null and .length is never evaluated. Your first example is effectively doing:
println("Length of the string is :" + null)
The !! operator says "throw a NullPointerException if the left side is null. Otherwise, we know it's not null on the right side". You can see this if you change your second example a little:
val userInput: String? = null
val inputLength:Int = userInput!!.length // throws NullPointerException
However, I'm not sure why are you are getting Unresolved reference: length. It looks like that the compiler is doing some optimization when you assign null directly to userInput, so rather than compiling it to a String? which throws an NPE at runtime, it knows the value is only null (not String?) at compile time, and therefore can't have the length property because null is not a reference.
You can force it to give you to NullPointerException by adding a layer of abstraction via a function call:
fun main(){
var userInput: String? = "foo"
userInput = alwaysNull()
val inputLength:Int = userInput!!.length // NullPointerException
}
fun alwaysNull(): String? = null
I don't see anything n the Null Safety documentation about the difference in behaviour between initializing in one line / via a function call vs. assigning null directly to a var though, so what's happening under the hood to get Unresolved reference is just a guess.
I saw scala code using cats in this post.
val a = Some(7)
val b = Some(9)
Applicative[Option].ap2(Some(add))(a,b)
And I tried migrating this code to kotlin and arrow like following.
Option.applicative()
.tupled(Some(7), Some(9))
.ap(Some(::add))
// works but dirty
fun add(tuple: Tuple2<Int, Int>): Int = tuple.a + tuple.b
// not work, compilation error
// fun add(a: Int, b: Int): Int = a + b
As you noticed, Tuple2 must be specified in the add function signature.
I searched the official document of arrow, but there is no apN function like ap2, ap3, ap4.
Is there any way to use the second function which not included Tuple2 type?
Once version 0.10 is available Arrow will have a .tupled() method on function types that handles this, so you will be able to write:
Option.applicative()
.tupled(Some(7), Some(9))
.ap(::add.tupled())
fun add(a: Int, b: Int) = a + b
for functions of up to 22 arguments.
I knew this can be achieved with for loop but I am looking for better solution.
createDummyString(1,'A') = 'A'
createDummyString(2.'A') = 'AA'
This will be used in hangman. Thank you.
You can do it like in the example below. To learn more about Strings read this: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html
fun createDummyString(repeat : Int, alpha : Char) = alpha.toString().repeat(repeat)
Addendum:
If you want to make it more kotlinesque, you can also define repeat as extension function on Char
fun Char.repeat(count: Int): String = this.toString().repeat(count)
and call it like this:
'A'.repeat(1)
CharSequence has an extension method for this.
fun CharSequence.repeat(n: Int): String // for any whole number
Example
println("A".repeat(4)) // AAAA
println("A".repeat(0)) // nothing
println("A".repeat(-1)) // Exception
Reference : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/repeat.html
I created a utility function using infix operator for this :
infix fun Int.times(s : CharSequence): CharSequence{
return s.repeat(this)
}
//Use like val twoAs = 2 times "A"
println(a) // AA
In Java we use
Integer.valueOf(str)
and
Long.valueOf(str)
to get the integer but how can we do the same in Kotlin?
You can just use toInt, toLong, and similar conversion extensions.
For example:
val i: Int = str.toInt()
val l: Long = str.toLong()
There's also toIntOrNull, etc. in case your strings might not be valid numbers:
val i: Int? = str.toIntOrNull()
Kotlin has extension methods for String class that do the same but more elegantly.
str.toInt()
str.toLong()
Note that you can write extension methods yourself as well.
Kotlin define extension function in StringNumberConversions.kt like toInt, toLong etc. These functions internally invoke standard java function like
java.lang.Integer.parseInt(...) or java.lang.Long.parseLong(...)
You can use them like :
"123".toInt()
"123".toLong()
These are Extension methods available for Strings to parse in KOTLIN:
str.toBoolean()
str.toInt()
str.toLong()
str.toFloat()
str.toDouble()
str.toByte()
str.toShort()
it is better to
val str = ""
val quotaInteger = str.toDouble().toInt()
cos sometime end give us like "123.22", if we use toInt(), it will throw out NumberFormatException
Doing some profiling, it seems my bottleneck is the Kotlin kotlin.CharSequence.split() extension function.
My code just does something like this:
val delimiter = '\t'
val line = "example\tline"
val parts = line.split(delimiter)
As you might notice, parts is a List<String>.
I wanted to benchmark using Java's split directly, which returns a String[] and might be more efficient.
How can I call Java's String::split(String) directly from Kotlin source?
You can cast a kotlin.String to a java.lang.String then use the java.lang.String#split since kotlin.String will be mapped to java.lang.String , but you'll get a warnings. for example:
// v--- PLATFORM_CLASS_MAPPED_TO_KOTLIN warnings
val parts: Array<String> = (line as java.lang.String).split("\t")
You also can use the java.util.regex.Pattern#split instead, as #Renato metioned it will slower than java.lang.String#split in some situations. for example:
val parts: Array<String> = Pattern.compile("\t").split(line, 0)
But be careful, kotlin.String#split's behavior is different with java.lang.String#split , for example:
val line: String = "example\tline\t"
// v--- ["example", "line"]
val parts1: Array<String> = Pattern.compile("\t").split(line, 0)
// v--- ["example", "line", ""]
val parts2 = line.split("\t".toRegex())
You can do this:
(line as java.lang.String).split(delimiter)
But it's not recommended to not use the kotlin.String as the compiler might tell you.