Swift: Как использовать sizeof?

Чтобы интегрироваться с C API при использовании Swift, мне нужно использовать функцию sizeof. В C это было легко. В Swift я попал в лабиринт ошибок типа.

У меня есть этот код:

var anInt: Int = 5 var anIntSize: Int = sizeof(anInt) 

Вторая строка имеет ошибку «NSNumber» не является подтипом «T.Type». Почему это и как я могу это исправить?

Используйте sizeof следующим образом:

 let size = sizeof(Int) 

sizeof использует этот тип в качестве параметра.

Если вы хотите размер переменной anInt вы можете передать поле dynamicType в sizeof .

Вот так:

 var anInt: Int = 5 var anIntSize: Int = sizeof(anInt.dynamicType) 

Или проще (указана пользователем102008):

 var anInt: Int = 5 var anIntSize: Int = sizeofValue(anInt) 

Обновлено для Swift 3

Будьте осторожны, что MemoryLayout.size означает что-то другое, чем sizeof в C / Obj-C. Вы можете прочитать эту старую нить https://devforums.apple.com/message/1086617#1086617

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

Подводя итог, MemoryLayout.size – это пространство, необходимое для одного экземпляра, в то время как MemoryLayout.stride – это расстояние между последовательными элементами в смежном массиве. MemoryLayout.stride в Swift совпадает с sizeof(type) в C / Obj-C.

Чтобы дать более конкретный пример:

 struct Foo { let x: Int let y: Bool } MemoryLayout.size // returns 8 on 64-bit MemoryLayout.size // returns 1 MemoryLayout.size // returns 9 MemoryLayout.stride // returns 16 because of alignment requirements MemoryLayout.alignment // returns 8, addresses must be multiples of 8 

Swift 3 теперь имеет MemoryLayout.size(ofValue:) который может динамически увеличивать размер.

Использование общей функции, которая, в свою очередь, использует MemoryLayout будет иметь неожиданные результаты, если вы, например, передадите ей ссылку на тип протокола. Это связано с тем, что, насколько мне известно, компилятор имеет всю информацию о типе, в которой ему нужно заполнить значения во время компиляции, что не очевидно при просмотре вызова функции.

В Xcode 8 с Swift 3 beta 6 нет функции sizeof (). Но если вы хотите, вы можете определить его для своих нужд. Эта новая функция sizeof работает так, как ожидалось, с массивом. Это невозможно с помощью старой встроенной функции sizeof.

 let bb: UInt8 = 1 let dd: Double = 1.23456 func sizeof  (_ : T.Type) -> Int { return (MemoryLayout.size) } func sizeof  (_ : T) -> Int { return (MemoryLayout.size) } func sizeof  (_ value : [T]) -> Int { return (MemoryLayout.size * value.count) } sizeof(UInt8.self) // 1 sizeof(Bool.self) // 1 sizeof(Double.self) // 8 sizeof(dd) // 8 sizeof(bb) // 1 var testArray: [Int32] = [1,2,3,4] var arrayLength = sizeof(testArray) // 16 

Вам нужны все версии функции sizeof, чтобы получить размер переменной и получить правильный размер типа данных и массива.

Если вы определяете только вторую функцию, то sizeof (UInt8.self) и sizeof (Bool.self) приведет к «8». Если вы определяете только первые две функции, то sizeof (testArray) приведет к «8».

Swift 4

Начиная с Xcode 9 теперь существует свойство, называемое .bitWidth , это обеспечивает другой способ записи sizeof: функции для экземпляров и целых типов:

 func sizeof(_ int:T) -> Int { return int.bitWidth/UInt8.bitWidth } func sizeof(_ intType:T.Type) -> Int { return intType.bitWidth/UInt8.bitWidth } sizeof(UInt16.self) // 2 sizeof(20) // 8 

Но было бы целесообразнее заменить sizeof: .byteWidth :

 extension FixedWidthInteger { var byteWidth:Int { return self.bitWidth/UInt8.bitWidth } static var byteWidth:Int { return Self.bitWidth/UInt8.bitWidth } } 1.byteWidth // 8 UInt32.byteWidth // 4 

Легко понять, почему sizeof: считается двусмысленным, но я не уверен, что его захоронение в MemoryLayout было правильным. См. Рассуждения о смещении sizeof: на MemoryLayout здесь .

  • Литье по типу Strange Swift
  • Аланофир-асинхронное завершениеHandler для запроса JSON
  • Нелегко реализовать простой синглтон в быстрой
  • В чем разница между использованием ARAnchor для вставки узла и непосредственной вставкой узла?
  • .toInt () удален в Swift 2?
  • Совместное использование данных между расширением общего доступа iOS 8 и основным приложением
  • Что такое Swift-эквивалент ответаSoSelector?
  • Отправка массива json через Alamofire
  • Является ли этот ответ от компилятора действительным?
  • Почему мое возrotation ноль, но если я нажму url в chrome / safari, я могу получить данные?
  • Параметр Inout в асинхронном обратном вызове не работает должным образом
  • Interesting Posts

    Java PriorityQueue с фиксированным размером

    Получение streamа RTSP с использованием библиотеки FFMPEG

    Есть ли исправление для ошибки «Слишком много открытых файлов в системе» на OS X 10.7.1?

    Как создать ярлык браузера, который откроет определенные страницы?

    В Mac OS, что такое сочетание клавиш для переключения между окнами одного и того же приложения?

    Просмотр рабочего стола Xubuntu в полноэкранном режиме под Virtualbox в Windows 8

    Соответствует ли лицензионное соглашение?

    Как настроить NDK с плагином Android Gradle 0.7

    Как я могу расширить вызов базовых classов вариационных шаблонов?

    Средство поиска и замены Mac OS X с поддержкой регулярных выражений

    Как показать и скрыть ActionBar с помощью AppCompat v.7

    Как переустановить приложение калькулятора Windows 10?

    Как я могу обрабатывать часовые пояса в моем webapp?

    Запуск нескольких версий Firefox

    Как я могу использовать несколько функций IF в Excel 2010?

    Давайте будем гением компьютера.