Using an instance in a function - swift

I’m new to Swift so I’ve been using the Swift Playgrounds app. On level 2 “Two Experts”, I initialized two experts:
let expert1 = Expert()
let expert2 = Expert()
What I wanted to do was create a function and pass whichever instance into it, access it’s methods etc, something like:
func actions(who: Item, distance: Int, turn: String) {
for 0 to distance {
who.moveforward()
}
ff turn == “Left” {
who.turnleft()
} else if turn == “Right” {
who.turnright()
}
}
Where who is expert1 or expert2.
I couldn’t find a way of doing this so had to write the same actions twice:
Func actions(who: String, distance: Int, turn:String) {
if who == “expert1” {
for 0 to distance {
expert1.moveforward()
} Etc
if who == “expert2” {
for 0 to distance {
expert2.moveforward()
} Etc
Is there a way of passing an instance into a function then perform certain actions if it’s of a particular class?

Since your experts is of type Expert, then the who parameter in your actions method should be of type Expert, if I understand the code correctly. Then you don't need two functions for each of the Experts. Let me know if I understood you correctly, and if it worked out.
Update
#Alexander mentioned that you can also have these methods in an extension on Expert, like so:
extension Expert {
func actions(distance: Int, turn: String) {
// Add method code here
}
}
When adding the method in an extension, every Expert object can use the method. So you could write expert1.actions(1, "Left") or something like that. Here's a link to the official Swift Programming Language guide about extensions.

Related

Swift Passing a Generic from a Function

I have the following function :
Amplify.API.query(request: .get(
self.getObjectForOCObject(ocObject: ocObject)!, byId: id)) { event in
The definition of the get function is :
public static func get<M: Model>(_ modelType: M.Type,
byId id: String) -> GraphQLRequest<M?> {
My getObjectForObject is as follows :
func getObjectForOCObject <M: Model>(ocObject:NSObject) -> M.Type?
{
if type (of:ocObject) == type(of: OCAccount.self)
{
return Account.self as? M.Type
}
return nil;
}
But I'm getting a"Generic Parameter 'M' could not be inferred. I get that the compiler cannot determine what type of object this is. However I don't know how to fix this. I need my getObjectForOCObject function to return what it is expecting. Essentially I'm trying to return the type of object based on the type of another object.
Normally this call is done this way and it works...
Amplify.API.query(request: .get(Account.self, byId: id)) { event in
I'm trying to avoid having to create a number of functions to handle each different Model in my code as that is being handled in higher up in the call hierarchy. Which is why I'm trying to do this. Otherwise I'm going to have to write essentially the same code in multiple places. In Objective C one can use the super class to pass objects around but the inheriting class still comes along with it. But with Swift being dynamically typed, I'm running into this issue.
The closest I've gotten is this... Changing the getObjectForOCObject return to Model.Type? as so :
func getObjectForOCObject (ocObject:NSObject) -> Model.Type?
{
if type (of:ocObject) == type(of: OCAccount.self)
{
return Account.self
}
return nil;
}
Then I get a Cannot convert value of type 'Model.Type?' to expected argument type 'M.Type' But aren't these essentially the same thing based on the .get function above?
Hoping for some insight here. Also, FYI, I'm pretty terrible with Swift so I'm certain I'm definitely doing some bad things in Swift here. I'm an expert with ObjC. I'm just trying to create a bridge between the two for this Swift library I'm using.

How to use inout variables with closures defined by other sources?

I'm relatively new to Swift and was wondering how I could achieve this exact thing.
I have a Swift process, and I want to toggle a flag on completion, and I have the following code:
task.terminationHandler = { process in
isTaskComplete.toggle()
}
I have this exact code duplicated in various views and was trying to convert it to a function, with my first attempt of referencing the isTaskComplete flag by using inout.
However, because terminationHandler itself defines the parameters of the closure it takes, there is no way for me to attach a secondary inout parameter. I was wondering if there was any way for me to reference the flag inside the closure and have the value be referenced?
For what it's worth in using Swift 5 and Xcode 11.5.
Any help will be greatly appreciated! Thanks :)
You can use protocols and protocol extensions for that.
protocol NameYourProtocol {
var task: TypeOfTask { get } // { get set } If you need
var isTaskComplete: Bool { get }
}
extension NameYourProtocol {
func handleTermination() {
task.terminationHandler = { process in
isTaskComplete.toggle()
}
}
}
And this is what you will do in every class you need to call it:
class Worker: NameYourProtocol {
// This will be required by protocol.
var task = TypeOfTask()
var isTaskComplete = false
init() {
// Call `handleTermination` where you need to.
handleTermination()
}
}

what is the difference between these two in swift 3 [duplicate]

In the Introduction to Swift WWDC session, a read-only property description is demonstrated:
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description)
Are there any implications to choosing the above approach over using a method instead:
class Vehicle {
var numberOfWheels = 0
func description() -> String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description())
It seems to me that the most obvious reasons for choosing a read-only computed property are:
Semantics - in this example it makes sense for description to be a property of the class, rather than an action it performs.
Brevity/Clarity - prevents the need to use empty parentheses when getting the value.
Clearly the above example is overly simple, but are there other good reasons to choose one over the other? For example, are there some features of functions or properties that would guide your decision of which to use?
N.B. At first glance this seems like quite a common OOP question, but I'm keen to know of any Swift-specific features that would guide best practice when using this language.
It seems to me that it's mostly a matter of style: I strongly prefer using properties for just that: properties; meaning simple values that you can get and/or set. I use functions (or methods) when actual work is being done. Maybe something has to be computed or read from disk or from a database: In this case I use a function, even when only a simple value is returned. That way I can easily see whether a call is cheap (properties) or possibly expensive (functions).
We will probably get more clarity when Apple publishes some Swift coding conventions.
Well, you can apply Kotlin 's advices https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties.
In some cases functions with no arguments might be interchangeable
with read-only properties. Although the semantics are similar, there
are some stylistic conventions on when to prefer one to another.
Prefer a property over a function when the underlying algorithm:
does not throw
complexity is cheap to calculate (or caсhed
on the first run)
returns the same result over invocations
While a question of computed properties vs methods in general is hard and subjective, currently there is one important argument in the Swift's case for preferring methods over properties. You can use methods in Swift as pure functions which is not true for properties (as of Swift 2.0 beta). This makes methods much more powerful and useful since they can participate in functional composition.
func fflat<A, R>(f: (A) -> () -> (R)) -> (A) -> (R) {
return { f($0)() }
}
func fnot<A>(f: (A) -> Bool) -> (A) -> (Bool) {
return { !f($0) }
}
extension String {
func isEmptyAsFunc() -> Bool {
return isEmpty
}
}
let strings = ["Hello", "", "world"]
strings.filter(fnot(fflat(String.isEmptyAsFunc)))
There is a difference:
If you use a property you can then eventually override it and make it read/write in a subclass.
Since the runtime is the same, this question applies to Objective-C as well. I'd say, with properties you get
a possibility of adding a setter in a subclass, making the property readwrite
an ability to use KVO/didSet for change notifications
more generally, you can pass property to methods that expect key paths, e.g. fetch request sorting
As for something specific to Swift, the only example I have is that you can use #lazy for a property.
In the read-only case, a computed property should not be considered semantically equivalent to a method, even when they behave identically, because dropping the func declaration blurs the distinction between quantities that comprise the state of an instance and quantities that are merely functions of the state. You save typing () at the call site, but risk losing clarity in your code.
As a trivial example, consider the following vector type:
struct Vector {
let x, y: Double
func length() -> Double {
return sqrt(x*x + y*y)
}
}
By declaring the length as a method, it’s clear that it’s a function of the state, which depends only on x and y.
On the other hand, if you were to express length as a computed property
struct VectorWithLengthAsProperty {
let x, y: Double
var length: Double {
return sqrt(x*x + y*y)
}
}
then when you dot-tab-complete in your IDE on an instance of VectorWithLengthAsProperty, it would look as if x, y, length were properties on an equal footing, which is conceptually incorrect.
From the performance perspective, there seems no difference. As you can see in the benchmark result.
gist
main.swift code snippet:
import Foundation
class MyClass {
var prop: Int {
return 88
}
func foo() -> Int {
return 88
}
}
func test(times: u_long) {
func testProp(times: u_long) -> TimeInterval {
let myClass = MyClass()
let starting = Date()
for _ in 0...times {
_ = myClass.prop
}
let ending = Date()
return ending.timeIntervalSince(starting)
}
func testFunc(times: u_long) -> TimeInterval {
let myClass = MyClass()
let starting = Date()
for _ in 0...times {
_ = myClass.prop
}
let ending = Date()
return ending.timeIntervalSince(starting)
}
print("prop: \(testProp(times: times))")
print("func: \(testFunc(times: times))")
}
test(times: 100000)
test(times: 1000000)
test(times: 10000000)
test(times: 100000000)
Output:
prop: 0.0380070209503174
func: 0.0350250005722046
prop: 0.371925950050354
func: 0.363085985183716
prop: 3.4023300409317
func: 3.38373708724976
prop: 33.5842199325562
func: 34.8433820009232
Program ended with exit code: 0
In Chart:
There are situations where you would prefer computed property over normal functions. Such as: returning the full name of an person. You already know the first name and the last name. So really the fullName property is a property not a function. In this case, it is computed property (because you can't set the full name, you can just extract it using the firstname and the lastname)
class Person{
let firstName: String
let lastName: String
init(firstName: String, lastName: String){
self.firstName = firstName
self.lastName = lastName
}
var fullName :String{
return firstName+" "+lastName
}
}
let william = Person(firstName: "William", lastName: "Kinaan")
william.fullName //William Kinaan
Semantically speaking, computed properties should be tightly coupled with the intrinsic state of the object - if other properties don't change, then querying the computed property at different times should give the same output (comparable via == or ===) - similar to calling a pure function on that object.
Methods on the other hand come out of the box with the assumption that we might not always get the same results, because Swift doesn't have a way to mark functions as pure. Also, methods in OOP are considered actions, which means that executing them might result in side effects. If the method has no side effects, then it can safely be converted to a computed property.
Note that both of the above statements are purely from a semantic perspective, as it might well happen for computed properties to have side effects that we don't expect, and methods to be pure.
Historically description is a property on NSObject and many would expect that it continues the same in Swift. Adding parens after it will only add confusion.
EDIT:
After furious downvoting I have to clarify something - if it is accessed via dot syntax, it can be considered a property. It doesn't matter what's under the hood. You can't access usual methods with dot syntax.
Besides, calling this property did not require extra parens, like in the case of Swift, which may lead to confusion.
An updated/fixed version of Benjamin Wen's answer incorporating Cristik's suggestion.
class MyClass {
var prop: Int {
return 88
}
func foo() -> Int {
return 88
}
}
func test(times: u_long) {
func testProp(times: u_long) -> TimeInterval {
let myClass = MyClass()
let starting = CACurrentMediaTime()
for _ in 0...times {
_ = myClass.prop
}
let ending = CACurrentMediaTime()
return ending - starting
}
func testFunc(times: u_long) -> TimeInterval {
let myClass = MyClass()
let starting = CACurrentMediaTime()
for _ in 0...times {
_ = myClass.foo()
}
let ending = CACurrentMediaTime()
return ending - starting
}
print("prop: \(testProp(times: times))")
print("func: \(testFunc(times: times))")
}
test(times: 100000)
test(times: 1000000)
test(times: 10000000)
test(times: 100000000)

Swift 3 nested functions vs closures

I have a large method that does some loading and calculating so it shows an activity indicator view to inform the users they should wait. The logic is pretty complex so there are 4 places in which the data processing might break or return (everything is done on closures). Anyway, I didn't want to repeat this code:
DispatchQueue.main.async {
activityView.hide()
activityView.removeFromSuperview()
}
in 4 places so I figured that I would write a nested function:
func removeActivityView() {
DispatchQueue.main.async {
activityView.hide()
activityView.removeFromSuperview()
}
}
but then I realised that in Swift I could also do:
let removeActivityView = {
DispatchQueue.main.async {
activityView.hide()
activityView.removeFromSuperview()
}
}
which is used exactly in the same way and does exactly the same from the user's point of view.
So what is the actual difference between one approach and the other?
They are the same in this case. In Swift:
Nested functions are closures that have a name and can capture values from their enclosing function.
Source
In fact, you could also do:
func foo() {
print("Foo!")
}
let bar = foo
Now foo() and bar() would yield the same result. This can be done for any function that takes in no arguments.
I'm not sure how/if the compiler differentiates these two. If anyone has more information with respect to that, I would be very interested!

What is the practical use of nested functions in swift? [duplicate]

This question already has answers here:
What is the benefit of nesting functions (in general/in Swift)
(3 answers)
Closed 6 years ago.
What is the practical use of nested functions? It only makes the code harder to read and doesn't make a particular case easy.
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backwards ? stepBackward : stepForward
}
Source
I think the core of your question is: Why not use private function instead of an ugly nested function?
Simply put, nested functions can ease readability and encapsulation.
Similarly one can ask, what's the practical use of local variables (of a function) vs instance variables? To me it's really the same question. Only that nested functions are less common.
Readability
A private function can still be accessed from other functions in your class. The same isn't true for nested functions. You're telling your developers, this only belongs to this function (contrary to private functions where they belong to the entire class). Back off and don't mess with it, if you need similar capability, go write your own!
The moment you see a private function you have to think, which function will call it. Is it the first function or the last? Let me search for it. Yet with a nested function you don't have to look up and down. It's already known which function will call it.
Also if you have 5 private functions, where 3 of them are called in a single public function then by nesting them all under the same public function you're communicating to other developers that these private functions are related.
In short, just as you don't want to pollute your public namespace, you don't want to pollute your private namespace.
Encapsulation
Another convenience is that it can access all the local parameters to its parent function. You no longer need to pass them around. This would eventually mean one less function to test, because you've wrapped one function inside another. Additionally if you're calling that function in a block of the non-nested function, then you don't have to wrap it into self or think about creating leaks. It's because the lifecycle of the nested function is tied to the lifecycle of its containing function.
Another use case would be when you have very similar functions in your class, say like you have:
extractAllHebrewNames() // right to left language
extractAllAmericanNames() // left to right language
extractAllJapaneseNames() // top to bottom language
Now if you have a private func named printName (that prints names), it would work if you switch the case based on language, but what if just you don't/can't do that. Instead you can write your own nested functions (They could all now have the exact same name. because each is in a different namespace.) inside each separate extract function and print the names.
Your question is somewhat similar, to why not use 'if else' instead of a 'Switch case.
I think it's just a convenience provided (for something that can be dealt without using nested functions).
NOTE: A nested function should be written before it's callsite within the function.
Error: use of local variable 'nested' before its declaration
func doSomething(){
nested()
func nested(){
}
}
No Error:
func doSomething(){
func nested(){
}
nested()
}
Similarly a local variable used in a nested function must be declared before the nested function
BE AWARE:
If you're using nested functions, then the compiler won't enforce self checks.
The compiler is not smart enough. It will NOT throw error of:
Call to method 'doZ' in closure requires explicit 'self.' to make capture semantics explicit
This could result in hard to find memory leaks. e.g.
class P {
var name: String
init(name: String) {
print("p was allocated")
self.name = name
}
func weaklyNested() {
weak var _self = self
func doX() {
print("nested:", _self?.name as Any)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
doX()
}
}
func stronglyNested() {
func doZ() {
print("nested:", name)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
doZ() // will NOT throw error of: `Call to method 'doZ' in closure requires explicit 'self.' to make capture semantics explicit`
}
}
deinit {
print("class P was deinitialized")
}
}
class H {
var p: P
init(p: P) {
self.p = p
}
}
var h1: H? = H(p: P(name: "john"))
h1?.p.weaklyNested()
h1 = nil // will deallocate immediately, then print nil after 2 seconds
var h2: H? = H(p: P(name: "john"))
h2?.p.stronglyNested()
h2 = nil // will NOT deallocate immediately, will print "john" after 2 seconds, then deallocates
tl;dr solution:
use weak var _self = self and inside the nested function reference to self with the weak reference.
don't use nested functions at all :( Or don't use instance variables inside your nested functions.
This part was written thanks to this original post from Is self captured within a nested function?
One use case is operations on recursive data structures.
Consider, for instance, this code for searching in binary search trees:
func get(_ key: Key) -> Value? {
func recursiveGet(cur: Node) -> Value? {
if cur.key == key {
return cur.val
} else if key < cur.key {
return cur.left != nil ? recursiveGet(cur: cur.left!) : nil
} else {
return cur.right != nil ? recursiveGet(cur: cur.right!) : nil
}
}
if let root = self.root {
return recursiveGet(cur: root)
} else {
return nil
}
}
Of course, you can transform the recursion into a loop, doing away with the nested function. I find recursive code often clearer than iterative variants, though. (Trade off vs. runtime cost!)
You could also define recursiveGet as (private) member outside of get but that would be bad design (unless recursiveGet is used in multiple methods).
There is the principle (since Objective-C) that "code can be data". You can pass code around, store it in a variable, combine it with other code. This is an extremely powerful tool. Frankly, if I didn't have the ability to treat code as data, most of the code I write would be ten times harder to write, and ten times harder to read.
Functions in Swift are just closures, so nested functions make perfectly sense, since this is how you write a closure when you don't want to use one of the many available shortcuts.
In your example, you can create a variable which is also a function like this:
var myStepFunction = chooseStepFunction(true)
myStepFunction(4)
The benefit of nested function is really nice. For example, let's say you are building an app for the calculator, you can have all your logic in one function, as the following:
func doOperation(operation: String) -> ((Double, Double) -> Double)? {
func plus(s: Double, d: Double) -> Double {
return s + d
}
func min(s: Double, d: Double) -> Double{
return s - d
}
switch operation {
case "+":
return plus
case "-" :
return min
default :
return nil
}
}
var myOperationFunction = doOperation("-")?(4, 4) // 0
var myOperationFunction2 = doOperation("+")?(4, 5) //9
In some cases, you are not allowed to see the implementation of some function, or not responsible for them. Then hidding them inside other function is really a good approach. For instance, assume that you colleague is reaponsible for developing the plus and min functions, he/she will do that, and you just use the outer function.
It is deferent from closure, because in clouser, you pass your logic to other logic, which will call yours. It is kind of plugin. For instance, after calling the http request, you can pass the code that you want your app to do when receiving the response from the server