Reputation: 459
I have initialized such string Array
var capitals = arrayOf("Tokyo","Moscow","Paris","Washington","Beijing")
But I have not specified its type to String. I thought when I use arrayOf constructor after the elements I should specify type.
Trying code below gives me errors property gettter and setter expected
Why I cannot have the type specified within <>
brackets?
var capitals = arrayOf("Tokyo","Moscow","Paris","Washington","Beijing"):Array<String>
Upvotes: 2
Views: 2847
Reputation: 300
And also you can as
Keyword to specific your type by:
var capitals = arrayOf("Tokyo", "Moscow", "Paris", "Washington", "Beijing") as Array<String>
Upvotes: 0
Reputation: 18617
I thought when I use arrayOf constructor after the elements I should specify type.
The compiler needs to know the type of every value — but it can often infer the type from what it already knows. So it's common¹ to omit the type.
In this case, the compiler knows that every element is a String
, so the list type can only be String
(or one of its supertypes: String?
, CharSequence
, CharSequence?
, Comparable<String>
, Comparable<String>?
, Any
, and Any?
). So it infers the most restrictive valid type: List<String>
.
Of course, you can manually specify the type if you want to. (You might want to be able to set nulls or other non-String values in the array later on, for example.) In fact, in this case there are two ways you could do that. You could specify the type parameter for arrayOf()
:
var capitals = arrayOf<Any?>("Tokyo", "Moscow", "Paris", "Washington", "Beijing")
Or you could specify the type of the variable you're assigning it to²:
var capitals: Array<Any?> = arrayOf("Tokyo", "Moscow", "Paris", "Washington", "Beijing")
Both have the same effect here, though the first is probably better. (It's shorter, which is always good! Also, it extends to more complex expressions.)
1: There are a few cases where it's good practice to specify the type explicitly, even when you don't need to. For example:
You might want to deliberately loosen the type, as shown above.
You might have a value returned from a Java function, where the compiler can't tell whether it should be nullable or not (a platform type). If you happen to know this, you can specify a nullable or non-nullable type accordingly.
You might have a function which is part of your public API, and you don't want to risk its type changing indirectly as a result of some internal changes. (This is only an issue for functions defined with an expression body, of course; you always have to specify a type for a block body unless it's returning Unit
.)
2: That second example shows that the compiler uses the surrounding context when inferring types. If it looked only at the String
parameters when inferring the type parameter for arrayOf()
, then that would give an Array<String>
— which can't be assigned to an Array<Any?>
variable, because Array
is not covariant!
But, as the language spec says:
the types of expressions may be derived not only from their arguments, but from their usage as well.
Upvotes: 2
Reputation: 8442
you have to specify type after variable declaration, not after initialization:
var capitals: Array<String> = arrayOf("Tokyo", "Moscow", "Paris", "Washington", "Beijing")
or you can explicitly set type parameter of arrayOf
:
var capitals = arrayOf<String>("Tokyo", "Moscow", "Paris", "Washington", "Beijing")
Upvotes: 5