Swift: How to access value of "_" parameter? - swift

I noticed that this is a valid function in Swift:
func test(_:String) {
print("How do I access '_'?")
}
How do I access the parameter?
EDIT
Additional question, is there a valid/good use-case for this?

How do I access the param?
You don't. Using that syntax you are explicitly saying you don't want to access the param.
Use case
Lets say you have access to a very powerful async API like the following.
func theAnswerToLife(success:(answer: String) -> (), failure:(error: NSError) -> ())
yes, of course I am keeping the implementation secret
Now if the function theAnswerToLife does find the answer it calls the success closure, otherwise failure is invoked.
You are forced to pass both closure/functions but you are really interested only in the answer, if something goes wrong you don't mind about the actual error.
So you could define
func tellEveryone(answer: String) {
print("The answer to life is " + answer)
}
func badNews(_:NSError) {
print("Something went wrong, we will try again tomorrow")
}
badNews can be passed as second param to theAnswerToLife and who in future will look at the code will immediately understand that badNews does not care about the received param.
theAnswerToLife(tellEveryone, failure: badNews)

This is so called wildcard matching pattern, and it is introduced just for the sake of not being able to use a parameter, because you just do not care about it.
From documentation:
A wildcard pattern matches and ignores any value and consists of an underscore (_). Use a wildcard pattern when you don’t care about the values being matched against.
You have to use a proper identifier if you need to access the argument value.
Regarding updated part of your question. I do not know why would you want to do this (just a wild idea), but if you want to completely hide argument names of a method of a public class but still be able to use them in private sub-class, you can do something like:
public class Foo {
func test(_: String, _: Int) {
print("[Ignored]")
}
}
private class Bar: Foo {
override func test(stringArgument: String, _ intArgument: Int) {
print("\(stringArgument) \(intArgument)")
}
}
Anyone external, using your library, would use abstract Foo without knowing parameter names of test method.

The point of using _ is that you are not interested in using the parameter. An example usage is this
if let _ = someVariable as? String {
//Do stuff here if someVariable is a string
//But I'm not interested in accessing the unwrapped value, so I set the unwrapped variable name to _
}

Related

What is the difference between "lazy var funcName: () -> Void" and regular function declaration in Swift

I have recently encountered such code block when I was working on a different codebase.
I was wondering is there any significant difference (in terms of memory impact etc.) between these two declarations other than syntactic ease? I regularly use lazy stored properties but I couldn't visualize how a function can be "lazy". Can you guys also enlighten me how functions are processed (or share an article explaining this topic) by the swift compiler as well?
Thanks in advance, wish you bug free codes.
A few differences I can think of off the top of my head:
With functions, you can use parameter labels to make the call site more readable, but since you can't add parameter labels to function types, you can't do that with the lazy var declaration.
// doesn't work
lazy var say: (message: String, to person: String) -> Void = {
...
}
// works
func say(message: String, to person: String) {
...
}
You can only invoke a function type with no parameter labels at all :( say("Hello", "Sweeper") instead of say(message: "Hello", to: "Sweeper").
lazy vars are variables, so someone could just change them:
helloFunc = { /* something else */ }
you could prevent this by adding a private setter, but that still allows setting it from within the same class. With a function, its implementation can never be changed at runtime.
lazy vars cannot be generic. Functions can.
// doesn't work
lazy var someGenericThing<T>: (T) -> Void = {
...
}
// works
func someGenericThing<T>(x: T) {
...
}
You might be able to work around this by making the enclosing type generic, but that changes the semantics of the entire type. With functions, you don't need to do that at all.
If you're implementing a language, the magic you need to implement 'lazy' as a feature is to make the value provided silently be wrapped in a function (of no arguments) that is automatically evaluated the first time the property is read.
So for example if you have
var x = SomeObject() // eagerly construct an instance of SomeObject
and
lazy var x = SomeObject() // construct an instance if/when someone reads x
behind the scenes you have, for the lazy var x, either x has not yet been read, or it has been and therefore has a value. So this is like
enum Lazy<T> {
case notReadYet(() -> T) // either you have a function that makes the initial T
case read(T) // or you have a value for T
}
var thing: Lazy<SomeObject> = .notReadYet { return SomeObject() }
and with a suitable property wrapper or other language magic, wrap the calls to the getter for thing with a switch on the case, which checks if you are in the notReadYet case, and if so automatically invoke the function to produce the T and then set the property to .read(t) for the particular value of t.
If you substitute in your type: () -> Void from your example you have something like:
var thing: Lazy<() -> Void> = .notReadYet({ return { print("Hello") } })
This is all rather odd because it's a void value and not much point making it lazy, e.g. it's not expensive to compute; it doesn't help break a two-phase initialisation loop, so why do it?

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.

Swift type(of:) function signature

I'm trying to implement function that returns simple name of value type:
func typeName(of value: Any) -> String {
return String(describing: type(of:value))
}
But when I try to call it before super.init call:
class SuperTest {
init(name: String) {
print(name)
}
}
class Test: SuperTest {
init() {
// super.init(name: String(describing: type(of: self)))
super.init(name: typeName(of: self))
}
}
Test()
it fails with:
'self' used before super.init call
which is totally clear to me.
But when I inline typeName(of:) body code (commented line) then it compiles and prints expected "Test" result.
Why does this magic happen and how can I use typeName(of:) before super.init() like type(of:)?
Also I can not find any information (function signature) about type(of:) in Swift docs or source code.
Even though it looks like it type(of:) is not a function, it is handled statically by the compiler as a Dynamic Type Expression. For this reason you can use it before calling super.init.
With your custom function the compiler doesn't know that you are not actually using the value so it can't allow the call.
Also I can not find any information (function signature) about type(of:)
Because it is not a function defined by the standard library. It is a primitive, i.e. it's part of the language. As the original Release Notes expressed it:
a new primitive function type(of:) has been added to the language [emphasis mine]
You might almost think of it as an operator. (That, indeed, was the whole point of its creation, as suggested in the original proposal.)

Parameterizing closures as generic based on parameter-list/return type

Is there a way to make a generic type signature for a closure such that I can later call it generically? In particular my question is how to deal with an unknown number of arguments.
I have an object that I’d like to call a series of closures on an update, and I’d like other objects to be able to register closures that they’d like to be called with that first object.
Closures aren’t hashable, but I’d like to be able to also unregister a closure, so I wound up creating a custom type to handle this based on a dictionary:
//T is the block signature such as Double->()
struct ClosureCollection<T> : SequenceType {
private var idx=0
var closureDict:[Int:(T,NSOperationQueue)]=[:]
mutating func addClosure(b:T) -> Int {
return addClosure(NSOperationQueue.mainQueue(),b)
}
mutating func addClosure(q:NSOperationQueue, _ b:T) -> Int {
closureDict[idx]=(b,q)
idx+=1
return idx-1
}
mutating func dropClosure(k:Int) {
closureDict.removeValueForKey(k)
}
func generate() -> AnyGenerator<(T,NSOperationQueue)> {
var dgen=closureDict.generate()
return AnyGenerator {
return dgen.next()?.1
}
}
}
This lets me use the collection in code like this:
Declare it:
private var distributionPoints=ClosureCollection<(CMDeviceMotion?,NSError?) -> ()> ()
Use it:
for (p,q) in distributionPoints {
q.addOperationWithBlock {p(dm,error)}
}
So far, all’s good but it requires the caller to follow a pretty specific pattern to use the collection that I'd like to hide. I’d like to extend this idea to where I can ask the collection to run the for loop itself using syntax something like
distributionPoints.runAllWith(dm,error)
The problem is with the runAllWith signature-- my current implementation is generic over the full closure signature because I don't know how to make the number of arguments to the closure generic. I suspect this can be done if I know the blocks accept one argument and return one argument, for example, by using two type placeholders, say T for the argument and U for the return value.
What I don’t seem able to do is make this generic across an unknown number of parameters. The type I’m creating doesn’t care what the structure of the block is, it just wants to accept closures with a certain signature and then provide a mechanism to call them by exposing an API that depends on the closure signature.
I don’t think there’s support for variadic generic parameters, so I can’t go down that road. Tuple-splat was deprecated.
Is there a way to do this without requiring the caller to bundle arguments into a tuple and then requiring a wrapper around each closure to unwrap a tuple of arguments and do a hand-crafted tuple splat?

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