두 가지 방법으로 할 수 있습니다. 구조체 인 경우 __traits(allMembers, T)
으로 가고 싶지만 클래스의 경우 __traits(derivedMembers, T)
과 같이 객체 상속 또는 다른 인스턴스에서 가비지를받지 못하게해야합니다 (원하는 경우 모든 회원들도 상속받을 것입니다).
구조체 또는 클래스가 될 수 있지만 확실하지 않은 일반적인 경우에는 안전을 위해 derivedMembers
을 사용해야합니다.
은 당신이 생각해야 할 것은 allMembers
및 derivedMembers
도 음부 등을 반환하기 때문에, 개인 회원을 방지하기 위해 __traits(compiles)
을 사용하는 것입니다
참조 : https://dlang.org/spec/traits.html#compiles
아마 이런 식으로 뭔가를 할 거라고 :
void validate(T)(T toValidate) {
import std.traits;
foreach (member; __traits(allMembers, T)) { // Loops through all members of "T"
static if(__traits(compiles, __traits(getMember, T, member))) { // Guards against private members
static if (mixin("hasUDA!(" ~ T.stringof ~ "." ~ member ~ ", Pattern)")) { // Checks if the member has the UDA "Pattern"
// TODO: pattern
}
static if (mixin("hasUDA!(" ~ T.stringof ~ "." ~ member ~ ", Min)")) { // Checks if the member has the UDA "Min"
// Gets the value from the UDA and stores it in a variable that we can use at runtime.
auto value = getUDAs!(mixin(T.stringof ~ "." ~ member), Min)[0].min;
// Creates an assert for validating the member's value.
mixin("assert(toValidate." ~ member ~ " >= value);");
}
static if (mixin("hasUDA!(" ~ T.stringof ~ "." ~ member ~ ", Max)")) { // Checks if the member has the UDA "Max"
// Gets the value from the UDA and stores it in a variable that we can use at runtime.
auto value = getUDAs!(mixin(T.stringof ~ "." ~ member), Max)[0].max;
// Creates an assert for validating the member's value.
mixin("assert(toValidate." ~ member ~ " <= value);");
}
}
}
}
당신은 다음과 같이 사용할 수있는 :
int main() {
StructToValidate structToValidate;
validate(structToValidate);
return 0;
}
참고 : 패턴을 구현하지 않았습니다.
사용할 수 있지만
:
https://dlang.org/phobos/std_regex.html
는 와우는 영리하다. Mixin 마법은 결코 나를 놀라게하지 않습니다. 나는 시간이 더있을 때 이것을 시도 할 것이다. – FatalCatharsis
작동하는 경우 대답을 받아주십시오 :)하지만 문자열 믹스 인은 놀랍습니다. 무엇이든 할 수 있습니다. – Bauss
매력처럼 작동합니다. 내가해야했던 유일한 조정은 elses를 제거하는 것이 었습니다. 그래서 멤버의 여러 속성들이 모두 처리 될 것입니다. – FatalCatharsis