Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift function alias

Tags:

alias

swift

How can I create an alias for a function in swift?

For example

I want to call

LocalizedString("key")

and it should call

NSLocalizedString("key", comment:"")

I saw typealias command but it looks like it works only for types.

like image 409
Daniel Gomez Rico Avatar asked Nov 27 '14 14:11

Daniel Gomez Rico


People also ask

What is an alias in Swift?

In programming terms, an alias is very similar. In Swift, typealias is a function that gives a new name, or an alias, to an existing type. This type can be a concrete type, like Double or a custom structure, a compound type, like tuples, or a complex closure type.

Why Typealias is used in Swift?

Swift Typealias is used to provide a new name for an existing data type in the program. Once you create a typealias, you can use the aliased name instead of the exsisting name throughout the program. Typealias doesn't create a new data type, it simply provides a new name to the existing data type.

What is Typealias Kotlin?

Type aliases provide alternative names for existing types. If the type name is too long you can introduce a different shorter name and use the new one instead. It's useful to shorten long generic types. For instance, it's often tempting to shrink collection types: typealias NodeSet = Set<Network.

What is type in Swift?

In Swift, there are two kinds of types: named types and compound types. A named type is a type that can be given a particular name when it's defined. Named types include classes, structures, enumerations, and protocols. For example, instances of a user-defined class named MyClass have the type MyClass .


2 Answers

The shortest one is:

let LocalizedString = { NSLocalizedString($0, comment:"") }

But, it's actually a new function. Just wrapping NSLocalizedString.


Maybe you can use undocumented @transparent attribute. It inlines function call. see this topic on Developer Forum.

@transparent LocalizedString(key:String) -> String {
    return LocalizedString(key, comment:"")
}

But it's not recommended. Moreover, as long as my tests, all of following codes eventually emit exact the same LLVM IR code with -O optimization.

script1: with @transparent

import Foundation
@transparent func LocalizedString(key:String) -> String {
    return LocalizedString(key, comment:"")
}
println(LocalizedString("key"))

script2: without @transparent

import Foundation
func LocalizedString(key:String) -> String {
    return LocalizedString(key, comment:"")
}
println(LocalizedString("key"))

script3: Direct NSLocalizedString call

import Foundation
func LocalizedString(key:String) -> String {
    return LocalizedString(key, comment:"")
}
println(NSLocalizedString("key", comment:""))

All of above are inlined to perform direct NSLocalizedString call.

But, the following code emits different:

script4: Closure wrapping

import Foundation
let LocalizedString = { NSLocalizedString($0, comment:"") }
println(NSLocalizedString("key", comment:""))

It's also inlined, but additional refcount instruction to LocalizedString is inserted.

So, as a conclusion, you should simply use this:

func LocalizedString(key:String) -> String {
    return LocalizedString(key, comment:"")
}
like image 197
rintaro Avatar answered Oct 30 '22 13:10

rintaro


Functions are named closures, so you can just assign a function to a variable:

let LocalizedString = NSLocalizedString

You can create pseudo-aliases for class/struct methods as well. Each method is actually a static (class) curried function, taking a class instance as its first parameter. So given a class:

class MyClass {
    var data: Int

    init(data: Int) {
        self.data = data
    }

    func test() {
        println("\(data)")
    }
}

you can assign the test method to a variable:

let test = MyClass.test

and then invoke it as:

var instance = MyClass(data: 10)
test(instance)()

UPDATE

I've just realized that I missed one important detail in your question: you want to hide the comment parameter. And my proposed solution doesn't allow that, whereas @rintaro's solution does.

However I use a different approach for that: I create a String extension implementing a computed property:

extension String {
    var localized: String {
        return NSLocalizedString(self, comment: "")
    }
}

and then I can just call it on any string variable or literal:

var string = "test_resource"
string.localized

"another_resource".localized
like image 32
Antonio Avatar answered Oct 30 '22 11:10

Antonio