Почему люди добавляют .0 на CGFloat?

https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/ImplementingACustomControl.html#//apple_ref/doc/uid/TP40015214-CH19-SW1 В этом руководстве

button.widthAnchor.constraint(equalToConstant: 44.0).isActive = true

константа имеет тип "44.0", а не "44".

Есть ли между ними разница?

Я измерил время методов.

func evaluateProblem(problemNumber: Int, problemBlock: () -> Void)
{
    print("Evaluating problem \(problemNumber)")

    let start = DispatchTime.now() // <<<<<<<<<< Start time
    let end = DispatchTime.now()   // <<<<<<<<<<   end time

    let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds // <<<<< Difference in nano seconds (UInt64)

    print("Time to evaluate problem \(problemNumber): \(nanoTime)")
}

evaluateProblem(problemNumber: 2) {
    let b: CGFloat = 44
    print(b)
}

evaluateProblem(problemNumber: 1) {
    let a: CGFloat = 44.0
    print(a)
}

Но более быстрый не фиксируется.


person 손지현    schedule 12.04.2020    source источник
comment
Похоже, ваш код на самом деле не запускает блок, или я что-то упускаю. Кроме того, проверка, просто запустив ее один раз, не даст разумных результатов. Кроме того, компилятор преобразует константу, если это необходимо, просто обычно в код помещаются числа с плавающей запятой/двойные числа как таковые, а не целые числа.   -  person Sami Kuhmonen    schedule 12.04.2020
comment
Никакой разницы, просто хорошая привычка. Делает для более чистого синтаксиса.   -  person Michael Wells    schedule 12.04.2020
comment
@DavidH Не так; он компилируется в CGFloat из-за ответа Роба. Swift не имеет неявных преобразований; если это выглядит так, то это на самом деле ExpressibleBy на работе.   -  person Jessy    schedule 12.04.2020


Ответы (1)


Вы можете инициализировать Double, Float, CGFloat, Int и т. д. целочисленными литералами, поскольку все вышеперечисленное соответствует ExpressibleByIntegerLiteral протокол. За кулисами инициализация литералом просто вызывает метод init(integerLiteral:) соответствующего типа.

Аналогичным образом, существует протокол ExpressibleByFloatLiteral, который обрабатывает инициализацию литералами с плавающей запятой, и этот протокол имеет инициализатор, который также должен быть реализован соответствующими типами.

Что касается того, что использовать, это вопрос личных предпочтений и стиля. Оба способа инициализации действительны, и если вы не выполняете тысячи инициализаций, разница в производительности будет незначительной.

person Rob    schedule 12.04.2020
comment
Я мог бы добавить, что IIRC, более ранние версии Swift (возможно, через Swift 2.x?) еще не имели возможности определять правильный тип без десятичной точки. Возможно, это результат того, что ExpressableByIntegerLiteral технически выполняет, но язык Swift претерпел такие масштабные изменения за первые 5 или около того лет, что иногда лучший ответ на подобный вопрос — это когда вы были вынуждены добавьте 1.0, чтобы вывести число с плавающей запятой над целым числом, но не больше. - person dfd; 12.04.2020
comment
@dfd Я думаю, что вы правы насчет инициализации через Swift 2.x, но ваш ответ, похоже, не объясняет, почему люди все еще используют десятичные знаки при инициализации. - person Rob; 12.04.2020
comment
Поэтому я не ответил, а прокомментировал. :-) Я могу предположить две возможные причины, а может быть и больше. (1) Либо по привычке ОП смотрит на устаревший код, либо человек, который кодирует, имеет опыт работы с другими языками, такими как GLSL, который действительно требует десятичной точки для чисел с плавающей запятой. (2) Удобочитаемость. Десятичная точка подразумевает некоторую точность над Int. Только что подумал о третьем — используя приведенный выше пример, предположим, что есть ограничения — может быть, на button, но, может быть, на вид на другом экране, но в том же приложении — которые на самом деле имеют константу более точную, чем 44,0? - person dfd; 12.04.2020