vacio arreglos array arrays swift swift3 swift-extensions

arrays - arreglos - string array in swift 3



Swift 3.0: error del compilador al llamar a la función global min<T>(T, T) en la extensión de matriz o diccionario (1)

No veo ninguna razón por la cual el compilador no pueda resolver esta llamada de función, por lo tanto, lo consideraría un error (ya se ha archivado; consulte SR-2450 ).

Parece ocurrir cada vez que se intenta llamar a una función de nivel superior con el mismo nombre, pero una firma inequívocamente diferente a un método o propiedad que es accesible desde el mismo alcance en un tipo dado (instancia o estático).

Un ejemplo aún más simple sería:

func foo(_ a: Int) {} struct Foo { func foo() {} // or static func foo() {}, var foo = 0, static var foo = 0 func bar() { foo(2) // error: argument passed to call that takes no arguments } }

Hasta que se solucione, una solución simple sería prefijar la llamada con el nombre del módulo en el que reside para desambiguar que se refiere a la función de nivel superior, en lugar de la instancia. Para la biblioteca estándar, eso es Swift :

extension Array { func smallestInt(first: Int, second: Int) -> Int { return Swift.min(first, second) } }

En Swift 4, el compilador tiene un mejor diagnóstico para este error (aunque el hecho de que todavía sea un error es un error IMO):

extension Array { func smallestInt(first: Int, second: Int) -> Int { // Use of ''min'' refers to instance method ''min(by:)'' // rather than global function ''min'' in module ''Swift'' // - Use ''Swift.'' to reference the global function in module ''Swift'' return min(first, second) } }

Aunque lo interesante es que el compilador ahora también advertirá al intentar llamar a un método de biblioteca estándar con el mismo nombre que una función de nivel superior stdlib:

extension Array where Element : Comparable { func smallest() -> Element? { // Use of ''min'' treated as a reference to instance method in protocol ''Sequence'' // - Use ''self.'' to silence this warning // - Use ''Swift.'' to reference the global function return min() } }

En este caso, como dice la advertencia, puede silenciarlo utilizando un self. explícito self. :

extension Array where Element : Comparable { func smallest() -> Element? { return self.min() } }

Aunque lo realmente curioso de esta advertencia es que no parece extenderse a funciones no definidas por stdlib:

func foo(_ a: Int) {} struct Foo { func foo() {} func bar() { foo() // no warning... } }

Después de convertir de Swift 2.2 a 3.0, mi extensión Array ya no se compila, porque contiene una llamada a la función de biblioteca estándar global min<T>(T,T) y muestra un error extra argument in call compilador extra argument in call .

Aquí hay una manera simple de reproducir el error:

extension Array { func smallestInt(first: Int, second: Int) -> Int { return min(first, second) // compiler error: "Extra argument in call" } }

Recibo el mismo error al agregar la misma función a una extensión de Dictionary , mientras que el mismo código se compila perfectamente en una extensión de otros tipos (por ejemplo, String o AudioBuffer ):

Al mirar la documentación de Array and Dictionary , encuentro que hay métodos de instancia en Sequence llamados public func min() -> Element? y public func min(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Element? . Mientras que String y AudioBuffer no tienen ningún tipo de función min(...) .

¿Es posible que esta sea la razón por la que no puedo llamar a la función global? El compilador no puede distinguir entre func min<T>(T,T) global func min<T>(T,T) y self.min(...) aunque tienen firmas completamente diferentes.

¿Es esto un error o una característica? ¿Qué estoy haciendo mal? ¿Cómo puedo llamar min(T,T) correctamente dentro de una extensión de Array ?