web-dev-qa-db-fra.com

swift 3 erreur: les étiquettes d'argument '(_ :)' ne correspondent à aucune surcharge disponible

Je viens de convertir un projet en Swift 3 et je ne peux pas comprendre l'erreur suivante.

public func currencyString(_ decimals: Int) -> String {

    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = decimals
    return formatter.string(from: NSNumber(self))!
}

la ligne de retour affiche une erreur "Les étiquettes d'argument '(_ :)' ne correspondent à aucune surcharge disponible"

Toute idée de ce qui doit changer pour résoudre ce problème

37
Mike U

Vous pouvez le faire de cette façon:

public func currencyString(_ decimals: Int) -> String {

    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = decimals
    return formatter.string(from: NSNumber(value: decimals))!
}

Parce que si vous vérifiez NSNumber vous obtiendrez un init prédéfini comme:

public init(value: Int)
56
Dharmesh

Pour clarifier la confusion quant à quelle est l'erreur,

NSNumber appelle la méthode NSNumber.init( value: X ) pour instancier un objet NSNumber.

"Les étiquettes d'argument '(_:)' Ne correspondent à aucune surcharge disponible"

Le code génère l'erreur car NSNumber n'est pas un type mais une classe avec des membres. "NSNumber(...)" instancie un objet de classe pour qu'il contienne la valeur '' de (1.0 / 1.29).

Ceci n'est pas une conversion de type ou un transtypage comme en C/C++. où vous essayez de transtyper le type permettant au compilateur de faire son travail.

float y = 1.3;
int x = int( y );

NSNumber n'est pas un type comme int, float, char

L'erreur entre en jeu car il existe plusieurs façons d'appeler NSNumber.init( value: type )

Swift exige que vous indiquiez spécifiquement que vous voulez que le membre 'valeur' ​​du NSNumber contienne la valeur x.

  let localRate = NSNumber( 1.0 / 1.29)
  var y = NSNumber( 0 )
  var b = NSNumber( false )



   let localRate = NSNumber(value: 1.0 / 1.29)
   var y = NSNumber( value: 0 )
   var b = NSNumber( value: false )

La confusion peut être en jeu parce que cela fonctionne.

w = String( "4" )

La classe String ne nécessite pas l'étiquette d'argument, alors que NSNumber requiert une étiquette d'argument de 'valeur:'

Peut-être est-ce dû à la façon dont IOS traite NSNumber comme provenant de l'héritage?

10
Vanderdecken

Et ça?

override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "backButton")
        self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "backButton")
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", barButtonSystemItem: UIBarButtonItemStyle.Plain, target: nil, action: nil)
}
2
The Hacking Gamer

Alors que la réponse acceptée montre comment NSNumber initialiseur doit être appelé correctement, il est bon de savoir qu'il n'y a aucune raison de convertir Swift nombres en NSNumber si nous utilisez la méthode string(for:) au lieu de string(from:).

return formatter.string(for: self)!
0
Sulthan