Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class have a variable name same as function name

Tags:

swift

I have the following class in Swift 4:

class AClass {
    var add: (Int) -> Int {
        return {
            num in
            return num + 1
        }
    }

    func add(_ num: Int) -> Int {
        return num + 20
    }
}

Note that the variable and function have the same name 'add'.

Now in some other place I have this code:

let a = AClass()
print(a.add(1))

I have run this code, and the result is 2 (which means the variable's block is called).

So here are the questions:

  1. Does the compiler always get the variable rather than call the function?

  2. Is there any way to call the function?

like image 662
NewSelf Avatar asked Feb 13 '19 04:02

NewSelf


People also ask

Can a variable name and function name be same?

Variables and functions have separate name spaces, which means a variable and a function can have the same name, such as value and value(), and Mata will not confuse them.

Can a variable name be same as class name?

No variable name should not has same name with **any** class name.

Can function name and variable name be same in Java?

Yes it's fine, mainly because, syntactically , they're used differently.

Can a function and a variable have the same name Python?

Bottom line: you can't have two things simultaneously with the same name, be it a function, an integer, or any other object in Python. Just use a different name.


2 Answers

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
like image 54
Hamish Avatar answered Sep 30 '22 06:09

Hamish


In Swift, instance methods are curried functions. Which means your add method is actually

static func add(_ self: AClass) -> (Int) -> Int

This is why the property gets chosen over the function. Calling AClass.add(a)(1) yelds the expected result, the function gets called.

Now, why does the compiler allows this name clashing if the first place? I'm not sure, but I assume it has to do with the fully qualified name of those two entities. The property is simply add, while the function is add(_:).

like image 38
Cristik Avatar answered Sep 30 '22 06:09

Cristik