Kotlin vs Swift: The Extension
Tags: iOS App Development, Mobile App Development, Android App Development, Kotlin, Swift

Learning Kotlin and Swift

Kotlin vs Swift: The Extension

Explore Kotlin and Swift together and learn their differences

Photo by Toa Heftiba on Unsplash

In SOLID Principle, the second one is the Open-Close Principle, i.e. Open for Extension and Close for Modification. Both Kotlin and Swift do have the capability to extends to a class on top of its ability for object inheritance.

The extension

Even though both Kotlin and Swift have extensions, they are different.

Kotlin has Function Extension

class MyClass { }

fun MyClass.extensionFunction() { }

Swift have Class Extension

class MyClass { }

extension MyClass {

func extensionFunction() { }

}

While both may look similar, but they do differ in capabilities. Below I’m sharing the advantage of each.

The function extension

In Kotlin, only have function extension support. On top of just extending a function to a class, below are it’s advantage compare to class extension

Nullable receiver extension function

Other than extending a function on a normal class, the extension function in Kotlin can also extend on a nullable class object.

class MyClass {

val localVal = "aaa"

fun doSomething() {

println("Normal doSomething")

}

}



fun MyClass?.doSomething() {

if (this == null) println("Null doSomething")

else doSomething()

}

This allows a null type of the class object also able to access the function.

Generic extension function

Another neat thing about Function Extension is the ability to extend from a generic template.

fun <T> T.strLen() {

println(toString().length)

}

The above can apply to apply the object to get the String and print the length. This capability is the one that enables Scope Function in Kotlin, e.g. the famous let

public inline fun <T, R> T.let(block: (T) -> R): R {

contract {

callsInPlace(block, InvocationKind.EXACTLY_ONCE)

}

return block(this)

}

There’s workaround in Swift by extending the NSObject class, as can be read here

Extend within class to access both scope

One can declare an extension function of another class within a class.

class MyClass {

val myClassLocalVariable = "myClassLocalVariable"

fun doSomething() {

println("Normal doSomething")

}

}



class WrapperClass {



private val wrapperLocalVariable = "wrapperLocalVariable"



fun MyClass.printBoth() {

println("$wrapperLocalVariable $myClassLocalVariable")

}

}

This makes the printBoth extension function to have access to both the variable of WrapperClass and MyClass .

Note: One can only access the public variable of MyClass , which is a limitation of function extension, which will be described below.

The class extension

In Swift, only have class extension support. Below are the advantage of class advantage Swift has over the function extension Kotlin has.

Access to private variable

With class extension, it is considered part of the class. Hence with that, the extended class scope can access the class private members.

class MyClass {

private let localVal = "localVal"

}



extension MyClass {

func printLocalVal() {

print(localVal)

}

}

This makes the extended function within the extended class can perform what a normal function in the class can possibly do.

Define a new constructor

Using class extension, we can create additional constructors specific to the need of the caller module

class SinkClass {

var sinkLocalVal: String

init(sinkInitVal: String) {

self.sinkLocalVal = sinkInitVal

}

} class SourceClass {

var sourceLocalVal: String

init(sourceInitVal: String) {

self.sourceLocalVal = sourceInitVal

}

} extension SinkClass {

convenience init(sourceObj: SourceClass) {

self.init(initVal: sourceObj.localVal)

}

} let source = SourceClass(sinkInitVal: "xxx")

let sink = SinkClass(sourceObj: source)

Using this approach, we have a cleaner code in converting one class object to the other.

Implement other protocol

Another nice bit about Class Extension is the ability to have the existing class Implement another Protocol (or Interface in Kotlin term).

final class MyClass { }

protocol MyProtocol { }

extension MyClass: MyProtocol { }



func doSomething(myProtocol: MyProtocol) { }

let myObj = MyClass()

doSomething(myProtocol: myObj)

Refer to the code above, clearly MyClass is final, and cannot be inherited. But with class extension, we can still make it to conform to the MyProtocol , and be used as MyProtocol and passing it into the doSomething function.