Hi-
Inside an init function in a generic protocol extension, I am currently using a
Mirror reflecting an instance of “Self" to iterate through all the Child
properties of the type adopting the protocol (Self).
Now, I want to be able to determine how many of Self's properties have a
default value prior to any init methods being called. I also would like to know
other metadata about these properties, such as what their access level
(private/internal/public/open) is, what their ownership is (weak, unowned,
etc.), whether they are declared on a parent class or on the existing
class/struct/enum, and ideally, get the highest access-level KeyPath to each
property under the current scope (since it’s in the type’s own init method now,
that scope should be “everything”).
However, so far I am finding Child to be extremely limiting. You can’t get any
children of Self.self; you have to reflect an instance. And then, all you get
is a string for the key of the property, which evidently cannot even be used to
form a KeyPath—not even using the #keypath(String) argument! You don’t get any
of the metadata I want via this method, from what I can tell. Am I missing
something…?
Forgetting about generic protocols for a second, even with a concrete type, I
can’t seem to figure out how one would be able to use KeyPaths in the manner
that I’m trying to do. Here is an example showing some of these limitations:
struct Foo {
private(set) var hasDefaultValue = true
private(set) var doesNotHaveDefaultValue: Bool
var default = Foo(hasDefaultValue: true, doesNotHaveDefaultValue: false)
}
init() {
for child in Mirror(reflecting: Foo.default) {
let key = #keypath(“Foo.” + child.label) // won’t compile; worthless
let path: WritableKeyPath<Foo, Bool> = \Foo.doesNotHaveDefaultValue //
compiles, so far so good… (false hope)
self[keyPath: path] = false // crashes even though it’s a
WritableKeyPath; worthless
… etc. etc.
}
}
Are these just bugs? Or is keyPath really this limited? Is there really no way
in Swift to use reflection to get all the information on a type’s properties,
not even from within the type’s own init method?
So far it seems that Mirror just returns for each property<T> a (label: String,
value: T) tuple where label is just a String, and value is whatever type the
property is. Meanwhile, in the C++ of the open source Swift compiler code, they
have a method allowing the compiler to determine whether or not a property has
a default value. I just want to know if there’s a way to do it from within
Swift, or if all these goodies are still only available in C++. If I need to
submit a PR to mod the compiler then I will, I just want to make sure I’m not
missing something here.
Thanks,
Jon
_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users