How to initialize and use function pointer in Swift - swift

Let's say I have this code snipped in the playground
import UIKit
internal final class TestClass {
internal final var funcPointer: () -> Void
init() {
self.funcPointer = self.func1() //Cannot assign value of type '()' to type '() -> Void'
}
internal final func func1() {
print("func1 is called!")
}
}
var testClass: TestClass = TestClass()
testClass.funcPointer()
Why do I get the shown error message within the init() method and how to initialize a function pointer correctly?
I have already seen this SO post and this tutorial but anyway I don't get it to work for a (Void) -> Void function...

To assign the closure to the property you have to remove the parentheses
self.funcPointer = self.func1
The subsequent error
self' used in method call 'func1' before all stored properties are initialized
can be fixed by declaring funcPointer implicit unwrapped optional
internal final var funcPointer: (() -> Void)!

Related

Enum parameter for function

enum FooEnum: Int {
case fooEnumCase = 13512
case fooEnumCase2 = 425156
}
class FooClass {
public func myFunction(chosenEnumCase: fooEnum) -> String {
/* Logic */
}
}
fooClass.myFunction(fooEnum.fooEnumCase)
I am getting the error:
FooEnum is not convertible to FooClass
What is wrong with this code?
First of all the code is very hard to read with lowercase class names.
Two issues:
With this syntax the method is supposed to be a class function.
public static func myFunction(chosenEnumCase: FooEnum) -> String
Which raises a new error
Missing argument label 'chosenEnumCase:' in call
and you have to add the parameter label:
enum FooEnum: Int {
case fooEnumCase = 13512
case fooEnumCase2 = 425156
}
class FooClass {
public static func myFunction(chosenEnumCase: FooEnum) -> String {
//logic
}
}
FooClass.myFunction(chosenEnumCase: FooEnum.fooEnumCase)
To explain the error message let's consider fooClass.myFunction:
let f: (fooClass) -> ((fooEnum) -> String) = fooClass.myFunction
It's a function that expects an instance of fooClass, and returns another function ((fooEnum) -> String). Whereas in your code it is fed an instance of type fooEnum.
Call that function on a instance:
let myInstance = fooClass()
myInstance.myFunction(chosenEnumCase: fooEnum.fooEnumCase)
Or make myFunction a class function:
public class func myFunction(chosenEnumCase: fooEnum) -> String
PS: To conform to the Swift naming conventions use FooEnum and FooClass.

Can't call a function inside the class instance

I have a class DiscoverUserInfo, which has a function compoundKeyValue. I need to call this function in line 23 (see pic below). But I am getting the following error:
Value of type '(NSObject) -> () -> DiscoverUserInfo' has no member
'compoundKeyValue'
You cannot call a method on self during initialization of self. Maybe you want to create a computed property instead?
public var compoundKey: String {
return self.compoundKeyValue
}
That will also allow you to remove the didSet handler from UserObject.
You may make the method compoundKeyValue static, as
static func compoundKeyValue() -> String {
return UserObject.UserId
}
and create compoundKey as
public var compoundKey: String = DiscoverUserInfo.compoundKeyValue()

How to declare dictionary with functions as values and keyed by integer?

struct Test {
func isOk () -> Bool{
return true
}
var mapping: [Int: () -> Bool] = [
1: isOk
]
func test() -> Bool {
return mapping[1]()
}
}
I got this error:
Cannot convert value of type '(Test) -> () -> Bool' to expected dictionary value type '() -> Bool'
Any idea? Thanks!
You're seeing this weird type ((Test) -> () -> Bool) because Swift instance methods are curried functions.
If making isOk into a static method is acceptable, you can do this:
struct Test {
static func isOk() -> Bool { //Make it static
return true
}
var mapping: [Int : () -> Bool] = [
1 : Test.isOk // Static method must be qualified by its parent type
]
func test() -> Bool { //Bool return value necessary
//TODO: remove force unwrapping.
return mapping[1]!() //subscripting a Dict might return nil
}
}
If isOk must remain as an instance method, you can do this:
struct Test {
func isOk() -> Bool {
return true
}
var mapping: [Int : (Test) -> () -> Bool] = [ //change type
1 : isOk
]
//the instance method received from the dict needs an instance to act on
func test(instance: Test) -> Bool { //Bool return value necessary
//TODO: remove force unwrapping.
return mapping[1]!(instance)() //curried function call
}
}
#AMomchilov is dead right about why this is happening. At static scope (such as in mapping's default value assignment), instance methods are curried functions – meaning that they return a function that take a given instance to operate on as a parameter, rather than implicitly operating on self (as self doesn't refer to an instance at static scope).
Another potential solution to the ones already proposed if you don't wish to make isOk a static method and would like mapping to remain a [Int : () -> Bool], is to make it lazy. This will allow you to access isOk in the assignment of mapping, as it's now at instance scope – therefore meaning the function type will be () -> Bool.
struct Test {
func isOk () -> Bool {
return true
}
lazy var mapping: [Int: () -> Bool] = [
1 : self.isOk
]
mutating func test() -> Bool {
// you need to think about situations where mapping[1] returns nil
// and deal with it in a more proper way than force unwrapping
return mapping[1]!()
}
}
The only caveat to this approach is that you'll need to mark test() as mutating – as the default value of a lazy variable will be set upon accessing it for the first time, thus mutating the struct.
Although a maybe even cleaner alternative (depending on the use case), is just to assign your function to the dictionary (or the dictionary itself) in the initialiser. This will allow you to keep mapping non-lazy, therefore meaning test doesn't have to be mutating.
struct Test {
func isOk () -> Bool {
return true
}
init() {
mapping[1] = isOk
}
var mapping = [Int: () -> Bool]()
func test() -> Bool {
// you need to think about situations where mapping[1] returns nil
// and deal with it in a more proper way than force unwrapping
return mapping[1]!()
}
}
Again, this ensures that you're at instance scope when assigning the method to the dictionary, thus ensuring that it has the signature () -> Bool.

What is the difference between static func and class func in Swift?

I can see these definitions in the Swift library:
extension Bool : BooleanLiteralConvertible {
static func convertFromBooleanLiteral(value: Bool) -> Bool
}
protocol BooleanLiteralConvertible {
typealias BooleanLiteralType
class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}
What's the difference between a member function defined as static func and another one defined as class func? Is it simply that static is for static functions of structs and enums, and class for classes and protocols? Are there any other differences that one should know about? What is the rationale for having this distinction in the syntax itself?
To be clearer, I make an example here,
class ClassA {
class func func1() -> String {
return "func1"
}
static func func2() -> String {
return "func2"
}
}
/* same as above
final class func func2() -> String {
return "func2"
}
*/
static func is same as final class func
Because it is final, we can not override it in subclass as below:
class ClassB : ClassA {
override class func func1() -> String {
return "func1 in ClassB"
}
// ERROR: Class method overrides a 'final` class method
override static func func2() -> String {
return "func2 in ClassB"
}
}
Is it simply that static is for static functions of structs and enums, and class for classes and protocols?
That's the main difference. Some other differences are that class functions are dynamically dispatched and can be overridden by subclasses.
Protocols use the class keyword, but it doesn't exclude structs from implementing the protocol, they just use static instead. Class was chosen for protocols so there wouldn't have to be a third keyword to represent static or class.
From Chris Lattner on this topic:
We considered unifying the syntax (e.g. using "type" as the keyword), but that doesn't actually simply things. The keywords "class" and "static" are good for familiarity and are quite descriptive (once you understand how + methods work), and open the door for potentially adding truly static methods to classes. The primary weirdness of this model is that protocols have to pick a keyword (and we chose "class"), but on balance it is the right tradeoff.
And here's a snippet that shows some of the override behavior of class functions:
class MyClass {
class func myFunc() {
println("myClass")
}
}
class MyOtherClass: MyClass {
override class func myFunc() {
println("myOtherClass")
}
}
var x: MyClass = MyOtherClass()
x.dynamicType.myFunc() //myOtherClass
x = MyClass()
x.dynamicType.myFunc() //myClass
I did some experiments in playground and got some conclusions.
TL;DR
As you can see, in the case of class, the use of class func or static func is just a question of habit.
Playground example with explanation:
class Dog {
final func identity() -> String {
return "Once a woofer, forever a woofer!"
}
class func talk() -> String {
return "Woof woof!"
}
static func eat() -> String {
return "Miam miam"
}
func sleep() -> String {
return "Zzz"
}
}
class Bulldog: Dog {
// Can not override a final function
// override final func identity() -> String {
// return "I'm once a dog but now I'm a cat"
// }
// Can not override a "class func", but redeclare is ok
func talk() -> String {
return "I'm a bulldog, and I don't woof."
}
// Same as "class func"
func eat() -> String {
return "I'm a bulldog, and I don't eat."
}
// Normal function can be overridden
override func sleep() -> String {
return "I'm a bulldog, and I don't sleep."
}
}
let dog = Dog()
let bullDog = Bulldog()
// FINAL FUNC
//print(Dog.identity()) // compile error
print(dog.identity()) // print "Once a woofer, forever a woofer!"
//print(Bulldog.identity()) // compile error
print(bullDog.identity()) // print "Once a woofer, forever a woofer!"
// => "final func" is just a "normal" one but prevented to be overridden nor redeclared by subclasses.
// CLASS FUNC
print(Dog.talk()) // print "Woof woof!", called directly from class
//print(dog.talk()) // compile error cause "class func" is meant to be called directly from class, not an instance.
print(Bulldog.talk()) // print "Woof woof!" cause it's called from Bulldog class, not bullDog instance.
print(bullDog.talk()) // print "I'm a bulldog, and I don't woof." cause talk() is redeclared and it's called from bullDig instance
// => "class func" is like a "static" one, must be called directly from class or subclassed, can be redeclared but NOT meant to be overridden.
// STATIC FUNC
print(Dog.eat()) // print "Miam miam"
//print(dog.eat()) // compile error cause "static func" is type method
print(Bulldog.eat()) // print "Miam miam"
print(bullDog.eat()) // print "I'm a bulldog, and I don't eat."
// NORMAL FUNC
//print(Dog.sleep()) // compile error
print(dog.sleep()) // print "Zzz"
//print(Bulldog.sleep()) // compile error
print(bullDog.sleep()) // print "I'm a bulldog, and I don't sleep."
To declare a type variable property, mark the declaration with the static declaration modifier. Classes may mark type computed properties with the class declaration modifier instead to allow subclasses to override the superclass’s implementation. Type properties are discussed in Type Properties.
NOTE
In a class declaration, the keyword static has the same effect as marking the declaration with both the class and final declaration modifiers.
Source: The Swift Programming Language - Type Variable Properties
Both the static and class keywords allow us to attach methods to a class rather than to instances of a class. For example, you might create a Student class with properties such as name and age, then create a static method numberOfStudents that is owned by the Student class itself rather than individual instances.
Where static and class differ is how they support inheritance. When you make a static method it becomes owned by the class and can't be changed by subclasses, whereas when you use class it may be overridden if needed.
Here is an Example code:
class Vehicle {
static func getCurrentSpeed() -> Int {
return 0
}
class func getCurrentNumberOfPassengers() -> Int {
return 0
}
}
class Bicycle: Vehicle {
//This is not allowed
//Compiler error: "Cannot override static method"
//static override func getCurrentSpeed() -> Int {
//return 15
//}
class override func getCurrentNumberOfPassengers() -> Int {
return 1
}
}
This example will clear every aspect!
import UIKit
class Parent {
final func finalFunc() -> String { // Final Function, cannot be redeclared.
return "Parent Final Function."
}
static func staticFunc() -> String { // Static Function, can be redeclared.
return "Parent Static Function."
}
func staticFunc() -> String { // Above function redeclared as Normal function.
return "Parent Static Function, redeclared with same name but as non-static(normal) function."
}
class func classFunc() -> String { // Class Function, can be redeclared.
return "Parent Class Function."
}
func classFunc() -> String { // Above function redeclared as Normal function.
return "Parent Class Function, redeclared with same name but as non-class(normal) function."
}
func normalFunc() -> String { // Normal function, obviously cannot be redeclared.
return "Parent Normal Function."
}
}
class Child:Parent {
// Final functions cannot be overridden.
override func staticFunc() -> String { // This override form is of the redeclared version i.e: "func staticFunc()" so just like any other function of normal type, it can be overridden.
return "Child Static Function redeclared and overridden, can simply be called Child Normal Function."
}
override class func classFunc() -> String { // Class function, can be overidden.
return "Child Class Function."
}
override func classFunc() -> String { // This override form is of the redeclared version i.e: "func classFunc()" so just like any other function of normal type, it can be overridden.
return "Child Class Function, redeclared and overridden, can simply be called Child Normal Function."
}
override func normalFunc() -> String { // Normal function, can be overridden.
return "Child Normal Function."
}
}
let parent = Parent()
let child = Child()
// Final
print("1. " + parent.finalFunc()) // 1. Can be called by object.
print("2. " + child.finalFunc()) // 2. Can be called by object, parent(final) function will be called.
// Parent.finalFunc() // Cannot be called by class name directly.
// Child.finalFunc() // Cannot be called by class name directly.
// Static
print("3. " + parent.staticFunc()) // 3. Cannot be called by object, this is redeclared version (i.e: a normal function).
print("4. " + child.staticFunc()) // 4. Cannot be called by object, this is override form redeclared version (normal function).
print("5. " + Parent.staticFunc()) // 5. Can be called by class name directly.
print("6. " + Child.staticFunc()) // 6. Can be called by class name direcly, parent(static) function will be called.
// Class
print("7. " + parent.classFunc()) // 7. Cannot be called by object, this is redeclared version (i.e: a normal function).
print("8. " + child.classFunc()) // 8. Cannot be called by object, this is override form redeclared version (normal function).
print("9. " + Parent.classFunc()) // 9. Can be called by class name directly.
print("10. " + Child.classFunc()) // 10. Can be called by class name direcly, child(class) function will be called.
// Normal
print("11. " + parent.normalFunc()) // 11. Can be called by object.
print("12. " + child.normalFunc()) // 12. Can be called by object, child(normal) function will be called.
// Parent.normalFunc() // Cannot be called by class name directly.
// Child.normalFunc() // Cannot be called by class name directly.
/*
Notes:
___________________________________________________________________________
|Types------Redeclare------Override------Call by object------Call by Class|
|Final----------0--------------0---------------1------------------0-------|
|Static---------1--------------0---------------0------------------1-------|
|Class----------1--------------1---------------0------------------1-------|
|Normal---------0--------------1---------------1------------------0-------|
---------------------------------------------------------------------------
Final vs Normal function: Both are same but normal methods can be overridden.
Static vs Class function: Both are same but class methods can be overridden.
*/
Output:
According to the Swift 2.2 Book published by apple:
“You indicate type methods by writing the static keyword before the method’s func keyword. Classes may also use the class keyword to allow subclasses to override the superclass’s implementation of that method.”
From Swift2.0, Apple says:
"Always prefix type property requirements with the static keyword when you define them in a protocol. This rule pertains even though type property requirements can be prefixed with the class or static keyword when implemented by a class:"
This is called type methods, and are called with dot syntax, like instance methods. However, you call type methods on the type, not on an instance of that type. Here’s how you call a type method on a class called SomeClass:

Anonymous class in swift

Is there an equivalent syntax or technique for Anonymous class in Swift?
Just for clarification Anonymous class in Java example here - http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
Thanks!
There is no equivalent syntax, as far as I know.
Regarding equivalent techniques, theoretically you could use closures and define structs and classes inside them. Sadly, I can't get this to work in a playground or project without making it crash. Most likely this isn't ready to be used in the current beta.
Something like...
protocol SomeProtocol {
func hello()
}
let closure : () -> () = {
class NotSoAnonymousClass : SomeProtocol {
func hello() {
println("Hello")
}
}
let object = NotSoAnonymousClass()
object.hello()
}
...currently outputs this error:
invalid linkage type for global declaration
%swift.full_heapmetadata* #_TMdCFIv4Test7closureFT_T_iU_FT_T_L_19NotSoAnonymousClass
LLVM ERROR: Broken module found, compilation aborted!
Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 1
You can also create a basic empty class that acts like a bare protocol, and pass a closure to the init function that overrides anything you want, like this:
class EmptyClass {
var someFunc: () -> () = { }
init(overrides: EmptyClass -> EmptyClass) {
overrides(self)
}
}
// Now you initialize 'EmptyClass' with a closure that sets
// whatever variable properties you want to override:
let workingClass = EmptyClass { ec in
ec.someFunc = { println("It worked!") }
return ec
}
workingClass.someFunc() // Outputs: "It worked!"
It is not technically 'anonymous' but it works the same way. You are given an empty shell of a class, and then you fill it in or override whatever parameters you want when you initialize it with a closure.
It's basically the same, except instead of fulfilling the expectations of a protocol, it is overriding the properties of a class.
For example, Java listener/adapter pattern would be translated to Swift like this:
protocol EventListener {
func handleEvent(event: Int) -> ()
}
class Adapter : EventListener {
func handleEvent(event: Int) -> () {
}
}
var instance: EventListener = {
class NotSoAnonymous : Adapter {
override func handleEvent(event: Int) {
println("Event: \(event)")
}
}
return NotSoAnonymous()
}()
instance.handleEvent(10)
(Crashing the compiler on Beta 2)
The problem is, you always have to specify a name. I don't think Apple will ever introduce anonymous classes (and structs etc.) because it would be pretty difficult to come with a syntax that doesn't collide with the trailing closures.
Also in programming anonymous things are bad. Naming things help readers to understand the code.
No anonymous class syntax in Swift. But, you can create a class inside a class and class methods:
class ViewController: UIViewController {
class anonymousSwiftClass {
func add(number1:Int, number2:Int) -> Int {
return number1+number2;
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
class innerSwiftClass {
func sub(number1:Int, number2:Int) -> Int {
return number1-number2;
}
}
var inner = innerSwiftClass();
println(inner.sub(2, number2: 3));
var anonymous = anonymousSwiftClass();
println(anonymous.add(2, number2: 3));
}
}
This is what I ended up doing (Observer pattern). You can use closures in a similar way you would use anonymous classes in Java. With obvious limitations of course.
class Subject {
// array of closures
var observers: [() -> Void] = []
// #escaping says the closure will be called after the method returns
func register(observer: #escaping () -> Void) {
observers.append(observer)
}
func triggerEvent() {
observers.forEach { observer in
observer()
}
}
}
var subj = Subject()
// you can use a trailing closure
subj.register() {
print("observerd")
}
// or you can assign a closure to a variable so you can maybe use the reference to removeObserver() if you choose to implement that method
var namedObserver: () -> Void = {
print("named observer")
}
subj.register(observer: namedObserver)
subj.triggerEvent()
// output:
// observerd
// named observer
If you want to inline a click handler in Java style fashion, first define your closure as a variable in your button class:
var onButtonClick: () -> Void = {}
Then add a method to accept the closure as parameter and store it in the variable for later use:
func onClick(label: String, buttonClickHandler: #escaping () -> Void) {
button.label = label
onButtonClick = buttonClickHandler
}
Whenever the closure should be executed, call it in your button class:
onButtonClick()
And this is how to set the action that should occur on click:
newButton.onClick(label: "My button") { () in
print("button clicked")
}
You can also accept multiple parameters. For example, a toggle button may be handled like this:
var buttonClicked: (_ isOn: Bool) -> Void { set get }
Simply use a struct for defining the interface via function values and then anonymously implement it from a function, as is a very common way to write objects in JavaScript.
The function is only required for creating a private scope for the object returned.
import Foundation
struct Logger {
let info: (String) -> ()
let error: (String) -> ()
}
func createSimpleLogger() -> Logger {
var count = 0
func number() -> Int {
count += 1
return count
}
return Logger(
info: { message in
print("INFO - #\(number()) - \(message)")
},
error: { message in
print("ERROR - #\(number()) - \(message)")
}
)
}
let logger = createSimpleLogger()
logger.info("Example info log message")
logger.error("Example error log message")
Output:
INFO - #1 - Example info log message
ERROR - #2 - Example error log message