As titled, I'm trying to simply assign
enum Input: Int {
case Release = GLFW_RELEASE
....
}
where
#define GLFW_RELEASE 0
but I get
'-' or expected, got 'GLFW_RELEASE'
isn't assumed as a readonly value?
As titled, I'm trying to simply assign
enum Input: Int {
case Release = GLFW_RELEASE
....
}
where
#define GLFW_RELEASE 0
but I get
'-' or expected, got 'GLFW_RELEASE'
isn't assumed as a readonly value?
Swift doesn't have a #define statement, as far as I know. It is not like C/C++/etc., where it runs the C preprocessor before parsing the code.
Indeed, it's from a C header. Sorry for not specifying that
In Swift, enum values must literals (see raw-value-style-enum-case in The Swift Programming Language. When you import GLFW_RELEASE
from C, the Swift version of it looks something like this:
var GLFW_RELEASE: Int32 { get }
This isn’t a literal, and thus you can’t use it as an enum value.
There’s a few things you can do here:
You can use the literal 0. Whether this is reasonable depends on the compatibility guarantees provided by the library you’re using. As GLFW_RELEASE
is a macro, the developer of that library can’t change the value in a binary compatibility fashion. However, they may only be guaranteeing source compatibility, in which case relying on the literal 0 would be an issue.
You can declare the enum in C, which has access to the GLFW_RELEASE
macro. Whether this makes sense depends on what other cases you have. If you have a case that can’t be represented in C — for example, it has an associated value — this approach won’t work.
You can avoid raw values and instead create a computed property that maps between the Swift ‘space’ and C ‘space’ values. This approach seems to make sense because the C values are Int32
not Int
.
ps In Swift style, enum cases begin with a lowercase letter, meaning it should be case release
not case Release
.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
Thanks eskimo, I also thought for a moment about a computed property or similar, but I was afraid it was too much over-engineered..
Moreover, since I'd need also to map forth and back enums from Swift and C (callbacks and methods) I dropped the idea
Ps: how would you do that?
how would you do that?
Nothing magic, just boilerplate code.
I’m not familiar with the API you’re using, so here’s an example based on BSD Sockets. Within BSD Sockets there’s an sa_family_t
type which is effectively an enum with values like AF_INET
, AF_INET6
, and so on. In Swift I might model this like so [1]:
enum AddressFamily {
case ip(version: Int)
case unix
}
This enum has an associated value, so there’s no way to represent it directly in C. Rather, you can make it raw representable like so:
extension AddressFamily: RawRepresentable {
init?(rawValue: sa_family_t) {
switch Int32(rawValue) {
case AF_INET: self = .ip(version: 4)
case AF_INET6: self = .ip(version: 6)
case AF_UNIX: self = .unix
default: return nil
}
}
var rawValue: sa_family_t {
switch self {
case .ip(version: 4): return sa_family_t(AF_INET)
case .ip(version: 6): return sa_family_t(AF_INET6)
case .unix: return sa_family_t(AF_UNIX)
default: fatalError()
}
}
}
Now you can map from C to Swift like this:
let afC: sa_family_t = … something …
guard let afSwift = AddressFamily(rawValue: afC) else {
…
}
and from Swift to C like this:
let afSwift: AddressFamily = … something …
let afC = afSwift.rawValue
I like this approach because it confines the C weirdness to the boundary between the C and Swift worlds, allowing my Swift code to work solely in terms of Swift.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
[1] Actually, this is a completely bonkers way to model this — unless you plan to add support for IPv5 (-: — but just go with the example.
Got it, thanks
You were right, quite boilerplate code.. what about allowing enum initialization from non literals? Would it make sense or is there a specific reason to have literal-only?
what about allowing enum initialization from non literals?
I can only really comment on the language as it currently stands. However, over on Swift Evolution there has definitely been chat about supporting compile-time expressions.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple