Comments (5)
I actually kinda do https://github.com/Zhuinden/guide-to-kotlin/wiki/2.)-Basic-Kotlin-Features#generics-t-blah-inout-and-star-projection-
But it's not that fleshed out because I use star projection when I can't find another way to do it. 🤔
Also I can't wrap my head around in
/out
and add them only when the compiler is yelling at me.
So in that sense, I do accept explanations that do not involve the term "covariance" and "contravariance" because nobody really understands those terms (and that is where all confusion comes from).
from guide-to-kotlin.
Ahh sorry! I'd missed that bit. To be honest, I'm on the same boat. I'm not super confident with when to use in/out but there is one part of the official documentation that did help - The two example just before star-projections.
Short snippet:
You can project a type with in as well:
fun fill(dest: Array<in String>, value: String) { ... }
Array<in String>
corresponds to Java's Array<? super String>
, i.e. you can pass an array of CharSequence
or an array of Object
to the fill()
function.
Perhaps it'd be worth including those examples as they're very Java-centric?
from guide-to-kotlin.
I get confused because you need to use @JvmSuppressWildcards
to prevent automatically adding ? extends ViewModel
, and I'm not sure why that happens.
from guide-to-kotlin.
I'm at working reading through https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-suppress-wildcards/index.html. I think it might only apply to out
? Luckily, the xmas holiday is coming :D
from guide-to-kotlin.
The first step is to understand why variance is important in the first place.
For example this java snippet that use Arrays (who have no variances) is unsafe:
void replace(Number[] numbers) {
numbers[0] = 1.0f;
}
void test() {
Integer[] array = new Integer[10];
replace(array);
// Our Integer[] array now contains a float!!
}
Take-away: Variance is really important to pass generics to other functions and when you work with collections of generics.
Now to undertand in
and out
in Kotlin, I ask myself whether the my generic class is a Producer
or a Consumer
or if it's both.
A producer-only (like List
) looks like this:
class Producer<out T >(
val beverage: T
){
fun produce() : T {
return beverage
}
}
A consumer-only class (like Comparable
) look like this
class Consumer<in T> {
fun consume(t: T) {
println("Drinking $t!")
}
}
Some class like MutableList
are both a Producer and a Consumer
class ProducerAndConsumer<T: Any> {
lateinit var value: T
fun updateValue(newValue: T) {
value = newValue
}
fun useValue() {
println(value)
}
}
MutableList
is an example that is both a Producer and a Consumer. In this case, the compiler won't let you assign a MutableList<A>
to a MutableList<B>
no matter what, for your own safety.
A complete example here
class Producer<out T : Beverage>(
val beverage: T
){
fun produce() : T {
return beverage
}
}
class Consumer<in T: Beverage> {
fun consume(t: T) {
println("Drinking $t!")
}
}
class BadProducer<T: Beverage>(
val beverage: T
) {
fun produce() : T {
return beverage
}
}
class BadConsumer<T: Beverage> {
fun consume(t: T) {
println("Drinking $t!")
}
}
interface Beverage
interface Alcohol: Beverage
object Coffee : Beverage
object Vodka: Alcohol
object Whisky: Alcohol
fun main(args: Array<String>) {
// OUT Generics
val colombia: Producer<Coffee> = Producer(Coffee)
val producer: Producer<Beverage> = colombia
// real-world example
val drinkWithModeration: List<Alcohol> = listOf(Whisky, Vodka)
val alcohols : List<Beverage> = drinkWithModeration
// without OUT Generics
val someOtherCountry : BadProducer<Coffee> = BadProducer(Coffee)
val badProducer: BadProducer<Beverage> = someOtherCountry // Compile ERROR: Type Mismatch
// real-world example
val drinkWithModeration2: MutableList<Alcohol> = mutableListOf(Whisky, Vodka)
val alcohols2 : MutableList<Beverage> = drinkWithModeration2 // Compile ERROR: Type Mismatch
// IN Generics
val someone = Consumer<Beverage>()
val me: Consumer<Coffee> = someone
// without IN Generics
val someFriend = BadConsumer<Beverage>()
val peter: BadConsumer<Vodka> = someFriend // Compile ERROR: Type Mismatch
}
from guide-to-kotlin.
Related Issues (12)
- Argument names are followed by colon not semi-colon before type HOT 2
- Collections initializers HOT 3
- data class and objects HOT 5
- Kotlin properties and encapsulation HOT 2
- Visibility modifiers: package visibility does exist HOT 4
- Unchecked exceptions and .use for try-finally
- setValue() in MyContract interface is not a setter HOT 1
- Multiple generic bounds
- Interface with val and vars HOT 1
- Use-cases for objects HOT 1
- No ternary operators HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from guide-to-kotlin.