如何从同一个Swift项目中的任何文件访问自定义函数?

时间:2016-12-02 22:29:10

标签: swift swift3

如果自定义函数的后缀运算符在文件范围内声明 - 就像在我的previous post中那样 - 必须有一种方法可以从同一个Xcode项目中的另一个Swift 3文件访问这样的函数。

Apple关于自定义函数的文档声明New operators are declared at a global level …所以我可以假设Swift 3的创建者会认为全局访问自定义函数很重要。但对于Swift的新手而言,我不会不言而喻。

基于我之前接受的答案(here)中的代码,我需要做什么才能从项目中其他位置的另一个文件访问自定义函数?

最终编辑

解决方案非常简单(见accepted answer),希望其他Swift新手也觉得它很有用。

postfix operator %是全局声明的Extension Int从另一个文件读取Int变量。 DoubleCGFloat以及Int的扩展也是可能的。

CustomOperators.swift

import UIKit

postfix operator %

extension Double {
    static postfix func % (n: Double) -> Double {
     return Double(n) /  100
    }
}

extension Int {
    static postfix func % (n: Int) -> Double {
        return Double(n) /  100
    }
}

extension CGFloat {
    static postfix func % (n: CGFloat) -> Double {
        return Double(n) /  100
    }
}

ViewController.swift

import UIKit

class ViewController: UIViewController {

    let test1: Double   = 93.7
    let test2: Int      = 80
    let test3: CGFloat  = 70

    override func viewDidLoad() {
        super.viewDidLoad()

    print(test1%)       // prints '0.937'
    print(test2%)       // prints '0.8'
    print(test3%)       // prints '0.7'

    }
}

感谢marosoiae,以及Martin R和unniversal的投入。

编辑2

Martin R的评论促使我尝试使用Utils中定义的自定义后缀函数,但是在文件范围而不是静态后缀函数。 Utils成为自定义函数的空类,所有自定义函数都在类外的文件范围内定义。

import UIKit

class ViewController: UIViewController {

let value: Int  = 25

override func viewDidLoad() {
    super.viewDidLoad()

    example1()
    example2()
}


func example1() {

    // 1. call to a function in Utils with an explicit value 
    // and nothing returned from Utils. 
    // Note this uses literal postfix syntax i.e. 25%

    Utils.25%


    // Debug message:
    // Type 'Utils' has no member '25'

    }


func example2() {

    // 2. call to a function in Utils with an argument 
    // declared in UIViewController and nothing returned from Utils

    Utils.(Int: value)%

    // Debug message
    // Expected member name following '.'

    }
}

Utils.swift现在可以编译,但是从Xcode使用这两个示例报告的调试消息进行编译,显然令牌“%'预计会立即跟随.'。

即使没有从Utils.swift返回变量,这显然也不是如何从项目中其他位置的文件中调用Utils.swift中的后缀函数。我的问题依然存在:我该怎么做?

编辑1

此时可能有助于包含一些代码,因此我创建了一个具有静态函数的类,遵循Unniversal的答案中使用的语法(尽可能)。我决定尝试静态函数,如果这些函数有助于避免使用应该由类/结构所拥有的方法来混淆全局范围。

文件1 - 实用程序

import UIKit

postfix operator %

class Utils {

    static func yourFunction(){
    //Do your stuff here
    }

    static func yourFunction1(value: Int) {
    print(value)
    }

    static postfix func % (percentage: Int) -> Double {
        return (Double(percentage) / 100)
    }    
}

静态函数%报告

    Member operator '%' must have at least one argument of type 'Utils'

一旦从另一个文件提供参数,我希望它会消失。

以下代码显示了我尝试为Utils中的静态函数提供参数的四种方法。我一次用一个例子运行项目

文件2 - UIViewController

import UIKit

class ViewController: UIViewController {

    let value: Int  = 25
    var percentage  = Double()


    override func viewDidLoad() {
        super.viewDidLoad()
//        example1()
//        example2()
//        example3()
//        example4()
    }





func example1() {

    // 1. call to a function in Utils with no argument and no return (i.e. suggested answer)

    Utils.yourfunction()

    // Debug messages:
    // Type 'Utils' has no member 'yourfunction'
    // Did you mean 'yourFunction'?
    // Did you mean 'yourFunction1'?

    }


func example2() {

    // 2. call to a function in Utils with argument and no return

    Utils.yourfunction1(Int: Int)

    // Debug messages:
    // Type 'Utils' has no member 'yourfunction'
    // Did you mean 'yourFunction'?
    // Did you mean 'yourFunction1'?

    }

func example3() {

    // 3. call to a function in Utils with argument and returning a value for percentage

    Utils.%() {
        return Int(percentage)
    }

    // Debug message:
    // Use of unresolved operator '.%'

    }

func example4()  {

    // 4. call to a function in Utils with argument and returning a value for percentage

    percentage = Utils.%(Int: value) -> Int {
        return Int(percentage)
    }

    // Debug messages:
    // Use of unresolved operator '.%'
    // Expected type before '->'
    // Expected type after '->'

    }
}

据我所知,静态函数Utils.yourFunctionUtils.yourFunction1无法从外部Utils访问,如示例1和2所示。后缀运算符%似乎导致Xcode报告Use of unresolved operator ‘.%’,如示例3和4所示。但是这些问题可能是我调整Unniversal使用的语法的方式。

2 个答案:

答案 0 :(得分:5)

在文件范围内声明的任何函数都将具有隐式作用域internal,并且将在项目/模块的其余部分中可见。

我建议您阅读access control guide以获取更多信息。

编辑:

我仍然不确定你要做什么,但看起来你正在将全局函数与静态方法和自定义运算符混合使用。

如果你想要的是声明一个可以在项目中的任何其他文件中使用的自定义运算符,那么解决方案就在你问题的documentation that you linked中。

因此,您需要为Int类型声明自定义%(如您所定义):

<强> CustomOperators.swift

postfix operator %

extension Int {

    static postfix func % (n: Int) -> Double {
        return Double(n) / 100
    }

}

<强> main.swift

print(90%) //outputs "0.9"

这就是它的全部。您只需全局声明运算符:postfix operator %并将运算符函数定义为Int类型的扩展中的静态方法。

现在,您可以在其他文件中使用新运算符(就像我在main.swift中所做的那样)。

答案 1 :(得分:3)

如果想要全局访问函数,我建议创建一个具有静态函数的类。例如

class Utils {
   static func yourFunction(){
      //Do your stuff here
   }
}

使用它:

Utils.yourfunction()