Question:
Why aren't the outputs the same for what are basically the same enumeration? Does Swift strip metadata from C (I assume it is stripped by the Compiler, then provided again by the Swift Interface File as though it is a normal Swift enum)?
Details:
I have two similar enumerations, one defined in C and one defined in Swift.
However I'm getting different print results, specifically the Swift Enum is able to print the key as a representational String (in this case first
), but the C Enum is only able to print the Enumeration name (in this case CNames
).
This is the output of the program,
Enumerations in Swift and C
Running on Swift 5
CNames is 1
first is 1
Program ended with exit code: 0
I assume the Swift main file is using the Swift Generated Interface.
This is what my project looks like:
Here's my native Swift enum, `SNames:
// // SNames.swift // TestAppMain // import Foundation public enum SNames : UInt { case unknown = 0 case first = 1 case middle = 2 case last = 3 }
Here is my C enum,
CNames
:#ifndef Names_h #define Names_h // NSUInteger type definition #import <Foundation/NSObjCRuntime.h> typedef NS_ENUM(NSUInteger, CNames) { NameUnknown = 0, NameFirst = 1, NameMiddle = 2, NameLast = 3, }; #endif /* Names_h */
Here's the generated Swift 5 Interface:
// NSUInteger type definition import Foundation.NSObjCRuntime public enum CNames : UInt { case unknown = 0 case first = 1 case middle = 2 case last = 3 }
Here is my bridging header:
#ifndef TestAppMain_Bridging_Header_h #define TestAppMain_Bridging_Header_h #import "CNames.h" #endif /* TestAppMain_Bridging_Header_h */
Finally my
main.swift
is:print("Enumerations in Swift and C") #if swift(>=5) print("Running on Swift 5") #endif let cFirst = CNames.first let sFirst = SNames.first // Swift Enum is able to output the specific // case (i.e first) whereas the C Enum // doesn't seem to have that info // CNames is 1 print("\(cFirst) is \(cFirst.rawValue)") // first is 1 print("\(sFirst) is \(sFirst.rawValue)")
CodePudding user response:
This is just a limitation of C. C enums are nothing more than a visually grouped set of integer constants.
You'll notice that you get the same limitations when applying @objc
to Swift enums:
enum NativeEnum: Int32 { case i = 123 }
print(NativeEnum.i) // => "i"
@objc enum ExportedEnum: Int32 { case i = 123 }
print(ExportedEnum.i) // => "ExportedEnum"