Skip to content

Latest commit

 

History

History
172 lines (132 loc) · 5.51 KB

Mutable, immutable collections.md

File metadata and controls

172 lines (132 loc) · 5.51 KB

Mutable, immutable collections

To adjust mutability, the let and var keywords are used. Additional mappings are required for mutable collections.

Explanations

Regardless of what signature is declared on the Kotlin side, mutable (MutableList) or not (List), both mutable and immutable collections can be passed on the Swift side.

In Kotlin:

//MutableImmutableCollections.kt

fun mutableListType(list: MutableList<Int>): MutableList<Int> {
    return mutableListOf(4, 5, 6).also { it.addAll(list) }
}

In Swift, mutability adjustment is done using the keywords var and let:

func collectionsMutabilityExample() {
    var mutableList: [KotlinInt] = [1, 2, 3]
    let notMutableList: [KotlinInt] = [1, 2, 3]

    mutableList = CommonTypesKt.listType(list: mutableList)
    let _ = CommonTypesKt.listType(list: notMutableList)
}

If you write the result of a function that returns List in a var variable, then you can safely change this collection, there will be no crashes:

func listTypeNoCrashes(){
    var list = CommonTypesKt.listType(list: [12, 34])
    list.append(2)
}

List / MutableList

With mutable collections there are different rules and different types. MutableList turns into NSMutableArray, but you can use a simple method of turning [KotlinInt] into NSMutableArray.

func listMutableListExample(){
    var mutableList: [KotlinInt] = [1, 2, 3]
    let notMutableList: [KotlinInt] = [1, 2, 3]

    let _ = MutableImmutableCollectionsKt.mutableListType(list: NSMutableArray(array: notMutableList))
    let _ = MutableImmutableCollectionsKt.mutableListType(list: NSMutableArray(array: mutableList))
}

Set / MutableSet

Let us declare two functions on the Kotlin side that use Set and MutableSet:

//MutableImmutableCollections.kt

fun setType(set: Set<Int>): Set<Int> {  
    return mutableSetOf(1, 2, 3).also { it.addAll(set) }  
}  
  
fun mutableSetType(set: MutableSet<Int>): MutableSet<Int> {  
    return mutableSetOf(4, 5, 6).also { it.addAll(set) }  
}

With the immutable version there is nothing remarkable, with mutable - on the Swift side you will need to cast types to KotlinMutableSet:

 func setMutableSetExample(){
    var mutableSet: Set<KotlinInt> = Set(arrayLiteral: 1, 2, 3)
    let notMutableSet: Set<KotlinInt> = Set(arrayLiteral: 1, 2, 3)

    mutableSet = MutableImmutableCollectionsKt.setType(set: mutableSet)
    let _ = MutableImmutableCollectionsKt.setType(set: notMutableSet)

    let _ = MutableImmutableCollectionsKt.mutableSetType(set: KotlinMutableSet(set: mutableSet))
    let _ = MutableImmutableCollectionsKt.mutableSetType(set: KotlinMutableSet(set: notMutableSet))
}

If you need to cast KotlinMutableSet to Swift Set, you need to do an explicit cast:

func mutableSetExample(){
    var mutableSet: Set<KotlinInt> = Set(arrayLiteral: 1, 2, 3)

    mutableSet = MutableImmutableCollectionsKt.mutableSetType(
        set: KotlinMutableSet(set: mutableSet)
    ) as! Set<KotlinInt>
}

This is possible because KotlinMutableSet is equivalent to NSMutableSet.

Map / MutableMap

Let us declare two functions on the Kotlin side that use Map and MutableMap:

//MutableImmutableCollections.kt

fun mapType(map: Map<String, Int>): Map<String, Int> {  
    return mutableMapOf(  
        "1" to 1,  
		"2" to 2,  
		"3" to 3  
	).also { it.putAll(map) }  
}  
  
fun mutableMapType(map: MutableMap<String, Int>): MutableMap<String, Int> {  
    return mutableMapOf(  
        "1" to 1,  
		"2" to 2,  
		"3" to 3  
	).also { it.putAll(map) }  
}

With the immutable version there is nothing remarkable, with mutable - on the Swift side you will need to cast types to KotlinMutableDictionary:

func mapMutableMapExample(){
    var mutableMap: Dictionary<String, KotlinInt> = Dictionary(dictionaryLiteral: ("1", 1), ("2", 2), ("3", 3))
    var mutableMapLiteral: [String: KotlinInt] = [
        "1": 1,
        "2": 2,
        "3": 3
    ]
    let notMutableMap: Dictionary<String, KotlinInt> = Dictionary(
        dictionaryLiteral: ("1", 1), ("2", 2), ("3", 3)
    )
    let notMutableMapLiteral: [String: KotlinInt] = [
        "1": 1,
        "2": 2,
        "3": 3
    ]
    
    mutableMap = MutableImmutableCollectionsKt.mapType(map: mutableMap)
    mutableMapLiteral = MutableImmutableCollectionsKt.mapType(map: mutableMapLiteral)
    let _ = MutableImmutableCollectionsKt.mapType(map: notMutableMap)
    let _ = MutableImmutableCollectionsKt.mapType(map: notMutableMapLiteral)
    
    let _ = MutableImmutableCollectionsKt.mutableMapType(
        map: KotlinMutableDictionary(dictionary: mutableMap)
    )
    let _ = MutableImmutableCollectionsKt.mutableMapType(
        map: KotlinMutableDictionary(dictionary: mutableMapLiteral)
    )
    let _ = MutableImmutableCollectionsKt.mutableMapType(
        map: KotlinMutableDictionary(dictionary: notMutableMap)
    )
    let _ = MutableImmutableCollectionsKt.mutableMapType(
        map: KotlinMutableDictionary(dictionary: notMutableMapLiteral)
    )
}

If you need to cast KotlinMutableDictionary to Swift Dictionary, you need to do an explicit cast:

mutableMap = types.mutableMapType(
	map: KotlinMutableDictionary(dictionary: mutableMap)
) as! Dictionary<String, KotlinInt>

This is possible because KotlinMutableDictionary is equivalent to NSMutableDictionary.


Table of contents