What is the meaning of the kotlin.String!
type and how could I make the following code compile?
fun withDefault<A>(computation: () -> A, default: A) =
try { computation() } catch (e: Exception) { default }
fun getHostname1() = withDefault(InetAddress.getLocalHost().getCanonicalHostName, "localhost")
The compiler prints the following error message:
Kotlin: Type inference failed: fun <A> withDefault(computation: () -> A, default: A): A
cannot be applied to
(kotlin.String!,kotlin.String)
Strings in Kotlin are represented by the type String . Generally, a string value is a sequence of characters in double quotes ( " ): val str = "abcd 123" Elements of a string are characters that you can access via the indexing operation: s[i] .
The most fundamental data type in Kotlin is the Primitive data type and all others are reference types like array and string.
The String class represents character strings. All string literals in Kotlin programs, such as "abc" , are implemented as instances of this class.
In Kotlin the Any type represents the super type of all non-nullable types. It differs to Java's Object in 2 main things: In Java, primitives types aren't type of the hierarchy and you need to box them implicitly, while in Kotlin Any is a super type of all types.
!
are called platform typesWhen interoperating with java, sometimes the java code contains nullability information such as @Nullable
and @NotNull
which kotlin uses to infer the types, for example @Nullable String name
makes name
to be of type String?
in kotlin.
If however there is no such information available on types coming from java, then those types are called platform types and are marked with a !
. In your case return type of getCanonicalHostName
doesn't contain any such information, hence its shown as kotlin.String!
From Kotlin in Action
PLATFORM TYPES
A platform type is essentially a type for which Kotlin doesn’t have nullability information; you can work with it as either a nullable or a nonnull type. This means, just as in Java, you have full responsibility for the operations you perform with that type. The compiler will allow all operations. It also won’t highlight as redundant any null-safe operations on such values, which it normally does when you perform a null-safe operation on a value of a non-null type. If you know the value can be null, you can compare it with null before use. If you know it’s not null, you can use it directly. Just as in Java, you’ll get a NullPointerException at the usage site if you get this wrong.
As for the error, it occurs because first argument to withDefault
is of functional type, but you are passing a kotlin.String!, which is clearly not a function.
When the type ends with !
it means that this is a platform type and compiler does not enforce null-safety for it. You can read about platform types in official blog, section Platform Types
.
I suggest such fix:
fun getHostname1() = withDefault({ InetAddress.getLocalHost().getCanonicalHostName() } , "localhost")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With