programacion - ¿Cómo acceder a una función personalizada desde cualquier archivo en el mismo proyecto Swift?
tipos de datos en swift (2)
Si el operador postfix de una función personalizada se declara en el alcance del archivo, como en mi publicación anterior , debe haber una forma de acceder a dicha función desde otro archivo Swift 3 en el mismo proyecto Xcode.
La documentación de Apple sobre funciones personalizadas establece que "Los nuevos operadores se declaran a nivel global ... " por lo que puedo suponer que los creadores de Swift 3 considerarían importante que se acceda a una función personalizada de forma global. Pero para un novato en Swift no es evidente cómo lo haría.
Basado en el código de mi respuesta aceptada anterior ( aquí ), ¿qué tendría que hacer para poder acceder a una función personalizada desde otro archivo en otro lugar del proyecto?
EDICIÓN FINAL
La solución es vergonzosamente simple (ver respuesta aceptada ) y es de esperar que otros novatos de Swift también la encuentren útil.
Un postfix operator %
se declara globalmente mientras que una Extension
de Int
lee una variable Int
de otro archivo. También son posibles las extensiones de Double
y CGFloat
, así como 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''
}
}
Gracias marosoiae, y también Martin R y unniversal por su aporte.
EDIT 2
Los comentarios de Martin R me llevaron a probar otro ejemplo con mi función personalizada de postfijo definida en Utils
pero en el alcance del archivo en lugar de como una función postfija estática. Utils
convierte en una clase vacía para funciones personalizadas, todas definidas en el alcance del archivo fuera de la clase.
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
ahora compila pero a partir de los mensajes de depuración que Xcode informa con ambos ejemplos, está claro que el token '' %
'' se espera inmediatamente después de '' .
''.
Incluso sin devolver una variable de Utils.swift
, obviamente no se trata de cómo llamar a una función de postfijo en Utils.swift
desde un archivo en otro lugar del proyecto. Mi pregunta sigue siendo: ¿cómo lo haría?
EDIT 1
En este punto, podría ser útil incluir algún código, así que creé una clase con funciones estáticas, siguiendo la sintaxis (en la medida de lo posible) utilizada en la respuesta de Unniversal. Decidí probar las funciones estáticas si ayudan a evitar saturar el alcance global con métodos que deberían ser propiedad de una clase / estructura.
Archivo 1 - Utils
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)
}
}
La función estática %
informes
Member operator ''%'' must have at least one argument of type ''Utils''
que esperaría desaparecer una vez que un argumento se suministre desde otro archivo.
El siguiente código muestra cuatro formas en que traté de proporcionar un argumento para las funciones estáticas en Utils. Ejecuté el proyecto con un ejemplo a la vez
Archivo 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 ''->''
}
}
Hasta donde puedo ver, no se puede acceder a las funciones estáticas Utils.yourFunction
y Utils.yourFunction1
externos, como se muestra en los ejemplos 1 y 2. Y el operador de posfijo %
parece hacer que Xcode informe " Use of unresolved operator ''.%''
, como se muestra en los ejemplos 3 y 4. Sin embargo, estos problemas podrían ser la forma en que adapté la sintaxis utilizada por Unniversal.
Si desea acceder a una función globalmente, le recomendaría crear una clase que tenga funciones estáticas. Por ejemplo
class Utils {
static func yourFunction(){
//Do your stuff here
}
}
Para usarlo:
Utils.yourfunction()
Cualquier función declarada en el alcance del archivo tendrá el alcance implícito internal
y será visible en el resto del proyecto / módulo.
Recomiendo leer la guía de control de acceso para más información.
Editar:
Todavía no estoy seguro de lo que intenta hacer, pero parece que está mezclando funciones globales con métodos estáticos y operadores personalizados.
Si lo que desea es declarar un operador personalizado que pueda usar en cualquier otro archivo del proyecto, la solución se encuentra en la documentación que ha vinculado en su pregunta.
Así que esto es lo que necesita para declarar un% personalizado (como lo definió) para el tipo Int:
CustomOperators.swift
postfix operator %
extension Int {
static postfix func % (n: Int) -> Double {
return Double(n) / 100
}
}
main.swift
print(90%) //outputs "0.9"
Eso es todo al respecto. Simplemente declare el operador globalmente: postfix operator %
y defina la función de operador como un método estático en una extensión del tipo Int.
Ahora puede usar su nuevo operador en otros archivos (como lo hice en main.swift
).