Kyle Cardoza writes: Erica, Is it considered bad style to typealias OpaquePointer when you have to deal with OpaquePointer values that point to different types? The typealiases make the code read so much nicer…
Using typealiases to create “pseudotypes” (where typealiases essentially duplicate a single type) neatly organizes your code. I endorse any solution that emphasizes semantics and supports readability. As OpaquePointer is not generic, it doesn’t encapsulate type information the way Array<Int>
or Set<String>
do:
// Both are typed to OpaquePointer, so nothing concrete // distinguishes the two roles. // let p1 = OpaquePointer(unsafeMutableRawPtr1) // let p2 = OpaquePointer(unsafeMutableRawPtr2)
Building convenience typealiases emphasizes the distinction between otherwise structurally identical uses. This differentiates each use-point and provides built-in “type commentary”:
typealias OpaqueType1Pointer = OpaquePointer typealias OpaqueType2Pointer = OpaquePointer let p1: OpaqueType1Pointer = OpaquePointer(rawPtr1) let p2: OpaqueType2Pointer = OpaquePointer(rawPtr2) // or, thanks Nil, directly: let p1 = OpaqueType1Pointer(rawPtr1) let p2 = OpaqueType2Pointer(rawPtr2)
You might consider an alternative. If you’re willing to trade off a little overhead against enhanced type safety, you might introduce a simple value type. Wrapping the opaque pointer enables you to use a type-specific initializer. Here’s an extremely rough example of what that might look like:
struct SometypeWrapper { let opaque: OpaquePointer init(value: Sometype) { opaque = OpaquePointer(Unmanaged .passRetained(value).toOpaque()) } }
What do you think? Good use of type aliases? Bad? Or should you always go with a wrapper? Let me know. Drop a note in the comments or send over a tweet.
Thanks, Mike Ash
3 Comments
You can also ‘initialize’ a typealias:
typealias OpaqueType1Pointer = OpaquePointer
typealias OpaqueType2Pointer = OpaquePointer
let p1 = OpaqueType1Pointer(rawPtr1)
let p2 = OpaqueType2Pointer(rawPtr2)
Would a generic typealias make sense here, to at least attribute the kind of pointer we’re talking about?
typealias OpaqeTypedPointer = OpaquePointer
let p1 : OpaqueTypedPointer<Array> = OpaquePointer(rawIntArrayPointer)
Looks like my generic parameter in the typealias declaration got filtered out there?