Swift: Print name of a function stored in a variable
Swift is a statically dispatched programming language. This results in Swift using memory addresses as much as possible when it needs to call a function. The side effect is the inability to capture the called function name, since in most of the cases it will be a simple memory address.
#function
works because this the construct gets replaced at compile time by the caller function (it's not a runtime construct).
If you have the debug symbols available, you could reconstruct the function name from a binary address, however this would require access to the dSYM infrastructure from within your application, which it's unlikely that you'll want to do, since shipping you app along with the debug symbols is an invitation for hackers to reverse engineer with your app.
Dynamically dispatched languages, like Objective-C, keep a reference to the called function (selector), but only if the called function is a method (i.e. a member function). Other languages, like Ruby, JavaScript, are interpreted languages, which makes the function name available at all times.
Print passed variable name in funciton parameter argument as string (Swift)
There is no way for printValue
func to know that you passed a value named positionX
because printValue
knows only about a variable named variable
.
What you could do is changing the printValue
func passing also the variable name as a String
. E.g:
func printValue(_ value: Double, _ name: String) {
print("\(name) = \(value)")
}
and call it like:
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad starts here")
let poisitionX: Double = 5.7
printValue(positionX, "positionX")
}
How to print variable name in swift?
You could change your struct to an enum
enum API: String {
case apiEndPoint = "example.com/profile?"
case apiEndPoint1 = "example.com/user?"
}
func doSomething(endPoint: API) {
print("\(endPoint): \(endPoint.rawValue)")
}
Example
doSomething(endPoint: .apiEndPoint)
apiEndPoint: example.com/profile?
How To Store Swift function in a variable
You have to help the compiler decide which function you want because it does not distinguish between parameter names when deciding if a function's signature is valid for assignment.
You can disambiguate your intent by being specific on the parameter names
let c: (left :String) -> () = cars(left:)
let c2: (right:String) -> () = cars(right:)
How can I have a variable and a function with same name in Swift
it's not possible, as they share the same namespace:
https://forums.swift.org/t/why-doesnt-swift-allow-a-variable-and-a-function-with-the-same-name/5038
Assign print function to a variable
I believe you've found a known bug (or limitation) of the Swift compiler.
The built-in print
function has three parameters. Parameter #1 is unlabeled and is type String ...
(variadic). Parameter #2 has label separator
, is type String
, and has a default value. Parameter #3 has label terminator
, is type String
, and has a default value. Since parameters #2 and #3 have default values, you can call it like print("hello")
.
Closures (like myPrint
) cannot use labeled parameters. So myPrint
takes three unlabeled parameters. Parameter #1 is type String ...
(variadic). Parameter #2 is type String
. Parameter #3 is also type String
. Closure parameters cannot have default values, so myPrint
requires all three parameters. You cannot call it like myPrint("hello")
, because you haven't passed anything for parameters #2 and #3 and they do not (and cannot) have default values.
In Swift, a variadic parameter (like parameter #1 of print
and myPrint
) consumes all arguments until in reaches a label. If you try to call myPrint("hello", " ", "\n")
, all three arguments will be assigned to parameter #1, and nothing will be assigned to parameters #2 and #3.
Since you cannot have labeled parameters in a closure, there is no way to call your myPrint
closure, because there is no way to pass values for parameters #2 and #3.
This is a known limitation. See SR-2475 and SR-494.
Class have a variable name same as function name
While both the property and method share the same base name add
, they have different full names. The method's full name is add(_:)
due to the fact that it has a parameter (with no argument label), and the property's full name is just add
. The fact that their full names differ is what allows them to overload each other.
If the method had no parameters, then the compiler would not have allowed the overload, as their full names are now both add
and therefore conflict:
class AClass {
var add: () -> Int {
return {
return 1
}
}
func add() -> Int { // error: Invalid redeclaration of 'add()'
return 2
}
}
Does the compiler always get the variable rather than call the function?
Assuming they have the same function type (such as in your example), then yes. There is an overload ranking rule that favours variables over functions:
// If the members agree on instance-ness, a property is better than a
// method (because a method is usually immediately invoked).
if (!decl1->isInstanceMember() && decl2->isInstanceMember())
score1 += weight;
else if (!decl2->isInstanceMember() && decl1->isInstanceMember())
score2 += weight;
else if (isa<VarDecl>(decl1) && isa<FuncDecl>(decl2))
score1 += weight;
else if (isa<VarDecl>(decl2) && isa<FuncDecl>(decl1))
score2 += weight;
lib/Sema/CSRanking.cpp
In order to call the method, you can use refer to it by its full name, for example:
let a = AClass()
print(a.add(_:)(1)) // 21
Related Topics
Anchoring Multiple Scenes in Realitykit
Partial Application of 'Mutating' Method Is Not Allowed
Toggle Sidebar in Swiftui Navigationview on MACos
How to Detect Text View Begin Editing and End Editing in Swift 3
Xcodebuild -Exportarchive Wont Allow Me to Specify Filename
Overriding Generic Function Error in Swift
Ios8 Swift Uisearchcontroller Hides Navigationbar
How to Print Escape Sequence Characters in Swift
Swift Error with Generic Array
Video Upload to Amazon S3 in Swift
Big O of Accessing a String with an Index in Swift 3.0
Realmswift Initialize List:Cannot Specialize a Non-Generic Definition
Currying in Swift, New Declaration Syntax in Future
Mutually Recursive Generic Enums
Provide Simple Method to Get Current Speed (Implementing Speedometer)
How to Stop/Cancel Playsoundfilenamed in Swift
Mfmailcomposeviewcontroller Error [Mc] Filtering Mail Sheet Accounts for Bundle Id