Как я могу исправить Не удается присвоить значение типа ‘Double’ ‘String?’ в Swift3

#swift3

#swift3

Вопрос:

Я новичок в swift, затем хочу написать подсчет ИМТ.

Ошибка Не удается присвоить значение типа ‘Double’ ‘String?’

появляется в label.text = GetBMI(H: myH, W: myW)

Как я могу это исправить?

    @IBAction func calBMI(_ sender: AnyObject) {
    if Height.text != nil amp;amp; Weight.text != nil {
        let myH : Double = (Height.text! as AnyObject).doubleValue
        let myW : Double = (Weight.text! as AnyObject).doubleValue
     label.text = GetBMI(H: myH, W: myW)
    }
    else {
        label.text = "Please enter your Height and Weight!"
    }
}

func GetBMI(H: Double, W: Double) -> Double {
    let height: Double = H / 100
    return  W / (height * height)
}
 

Ответ №1:

Вы можете найти несколько потоков, описывающих, как исправить Не удается присвоить значение типа ‘Double’ для ‘String?’, Но, к сожалению, эти потоки могут не указывать на некоторые плохие части вашего кода.

Если бы я исправил все такие части:

 @IBOutlet var heightField: UITextField! //Renamed `Height` to `heightField`
@IBOutlet var weightField: UITextField! //Renamed `Weight` to `weightField`
@IBAction func calBMI(_ sender: AnyObject) {
    if //Optional binding (using `if-let`) is the more preferred way than `!= nil` and forced unwrapping.
        let heightText = heightField.text,
        let weightText = weightField.text,
        //You should not use `(... as AnyObject).doubleValue` to convert `String` to `Double`
        //and should check if the text values are valid representation of Double
        let myH = Double(heightText),
        let myW = Double(weightText)
    {
        //This is the key point for the error "Cannot assign value of type 'Double' to 'String?'"
        label.text = String(getBMI(h: myH, w: myW)) //You need to convert `Double` to `String`
    }
    else {
        label.text = "Please enter your Height and Weight!"
    }
}

//Renamed `GetBMI(H:W:)` to `getBMI(h:w:)`
func getBMI(h: Double, w: Double) -> Double {
    let height: Double = h / 100
    return  w / (height * height)
}
 

Некоторые моменты:

  • Имена свойств должны представлять функцию содержимого. В вашем коде вы используете height и weight в качестве Double значений, поэтому вам лучше назвать UITextField s (предполагая Height , что и Weight являются UITextField s ) чем-то другим. Я переименовал их в heightField и weightField .
  • Тестирование с != nil использованием и последующее применение принудительной развертки ( ! ) не является предпочтительным способом, вам лучше избегать использования ! как можно больше. Лучше использовать необязательную привязку — if-let .
  • Вы не должны использовать (... as AnyObject).doubleValue для преобразования String в Double . Вы можете использовать инициализатор Double для преобразования String в Double (# 1). Который возвращает Optional<Double> , поэтому лучше включите их if-let .
  • Вы не можете напрямую присвоить Double значение свойству типа String? . Вы можете использовать инициализатор String для преобразования Double в String (# 1).
  • В Swift вы обычно используете идентификатор с заглавной буквы только для типов, поэтому я переименовал GetBMI(H:W:) в getBMI(h:w:) .

(#1) Использование инициализаторов при преобразовании между String и Double является своего рода упрощенным способом. Этого может быть достаточно для создания учебного кода калькулятора BMI, но может быть недостаточно для реальных приложений. Рассмотрите возможность использования NSNumberFormatter для реальных приложений.

Жирные линии обязательны или настоятельно рекомендуются.

Ответ №2:

 label.text = String(GetBMI(H: myH, W: myW)) 
 

Ваша функция возвращает значение double, label.text будет принимать только строку. Следовательно, вы получаете сообщение об ошибке: невозможно присвоить значение типа ‘Double’ ‘String?.

Вопросительный знак в ошибке мог бы сбить вас с толку. Что? на ‘String?’ есть, потому что label.text МОЖЕТ быть пустым, поэтому его ‘необязательный’ ie: может иметь или не иметь значение. Противоположность ! который явно объявляет, что существует значение и равно != nil.