Как я могу работать с Int и CGFloat?
В Objective-C я могу выполнить следующую операцию:
Objective-C код:
CGFloat width = CGRectGetWidth(mView.bounds);
CGFloat total = width*[myArray count];
но в Swift это вызовет ошибку:
Не удалось найти перегрузку для '*', которая принимает предоставленные аргументы
Как я могу избежать этой ситуации изящно?
Ответы
Ответ 1
Сначала создайте некоторые демо-данные
let array: NSArray = ["a", "b", "c"] //you could use a Swift array, too
let view = UIView() //just some view
Теперь все остальное работает почти так же, как в Obj-C
let width: CGFloat = CGRectGetWidth(view.bounds)
или просто
let width = CGRectGetWidth(rect) //type of the variable is inferred
и всего:
let total = width * CGFloat(array.count)
Обратите внимание, что мы должны добавить cast CGFloat
для array.count
. Obj-C неявно отбрасывал NSUInteger
в CGFloat
, но Swift не имеет неявных приведений, поэтому мы должны добавить явный.
Ответ 2
В Swift вы не можете сразу умножить два числа разных типов (NSNumber, Int, Double и т.д.). Ширина CGRect имеет тип с плавающей точкой, а количество массивов - целочисленного типа. Вот рабочий пример:
let myArray: Int[] = [1,2,3]
let rect: CGRect = CGRect(x:0,y:0,width:100,height:100)
let total: Double = rect.size.width * Double(myArray.count)
Ответ 3
Swift не разрешает операции между двумя номерами разных типов. Поэтому, прежде чем умножить ваш array.count
(Int
) на вашу ширину (CGFloat
), вам нужно привести его к CGFloat
.
К счастью, Swift предоставляет простой инициализатор CGFloat
init(_:)
который создает новый CGFloat
из Int
. Этот инициализатор имеет следующую декларацию:
init<Source>(_ value: Source) where Source : BinaryInteger
Создает новое значение, округленное до ближайшего возможного представления.
Пример кода Swift 5 Playground ниже показывает, как выполнить вычисления с помощью инициализатора CGFloat
:
import UIKit
import CoreGraphics
// Set array and view
let array = Array(1...3)
let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
let view = UIView(frame: rect)
// Perform operation
let width = view.bounds.width
let total = width * CGFloat(array.count)
print(total) // prints: 300.0