형식 매개 변수를 사용하는 추상 클래스를 만들고 해당 클래스의 생성자에 다른 동작을 전달해야합니다.제네릭 형식 매개 변수 와일드 카드
abstract class Action<Tc> {
public function __construct(private ?Action<*> $onSuccess = null) {}
}
유형 매개 변수 와일드 카드를 어떻게 표현할 수 있습니까? "?" (자바) 또는 "_"(스칼라) 해킹?
형식 매개 변수를 사용하는 추상 클래스를 만들고 해당 클래스의 생성자에 다른 동작을 전달해야합니다.제네릭 형식 매개 변수 와일드 카드
abstract class Action<Tc> {
public function __construct(private ?Action<*> $onSuccess = null) {}
}
유형 매개 변수 와일드 카드를 어떻게 표현할 수 있습니까? "?" (자바) 또는 "_"(스칼라) 해킹?
와일드 카드가 확실하지 않지만 원하는 것을 얻을 수 있습니까? 나는이 HHVM 3.1.0에 대해 실행하면
<?hh
abstract class Action<T1 as Action, T2> {
public function __construct(private ?T1 $onSuccess = null, private ?T2 $bla = null) {}
}
class ActionA<T1 as Action, T2> extends Action<T1, T2> {}
class ActionB<T1 as Action, T2> extends Action<T1, T2> {}
class ActionC<T1 as Action, T2> extends Action<T1, T2> {}
$action = new ActionA(new ActionB(new ActionC(null)));
var_dump($action);
, 내가 얻을 : "오류"를
object(ActionA)#1 (2) {
["onSuccess":"Action":private]=>
object(ActionB)#2 (2) {
["onSuccess":"Action":private]=>
object(ActionC)#3 (2) {
["onSuccess":"Action":private]=>
NULL
["bla":"Action":private]=>
NULL
}
["bla":"Action":private]=>
NULL
}
["bla":"Action":private]=>
NULL
}
그리고 3.1.0 유형 검사는 반환하지 않습니다.
그러나 추상 클래스에 대한 T1 as Action
문은 적용되지 않습니다. 예를 들어, 나는에 인스턴스화 라인을 변경할 수 있습니다
$action = new ActionA(new ActionB(new ActionC(new DateTime())));
을 그리고 그것은 여전히 오류를 반환하지 않는 typechecker으로, 미세 함께 윙윙 거린다. 그리고 이것은 클래스 정의를 <?hh // strict
으로 자신의 파일로 가져간 후입니다.
정말 대답은 아니지만 아마도 닫을 수 있습니까? 위의 동작은 Hack이 이런 종류의 패턴에 몇 가지 문제가 있음을 암시 할 수 있습니다. 실제로 예를 들어, 당신이 실제로 필요하지 않은 더미 유형 매개 변수를 지정하는 것입니다 얻을 수있는 가장 가까운 있도록
'T1 as Action'은 type 매개 변수를'Action
해킹
abstract class Action<Tc, Ta> {
public function __construct(private ?Action<Ta> $onSuccess = null) {}
// ...
}
는 방법을 정확하게에 따라, 지금 와일드 카드 유형 매개 변수가없는 당신 그러나
abstract class Action<Tc, Ta, To as Action<Ta>> {
public function __construct(private ?To $onSuccess = null) {}
// ...
}
, 나는 여부 "더미"유형의 위의 위의 질문 : $onSuccess
멤버 변수를 사용하여, 당신은 나중에 결정하는 Action<T>
의 일부 특정 서브 클래스로 할 수 있습니다, 그래서 당신이 뭔가를 할 수 있습니다 ar 실제로는 더미인데 - Action<T>
의 광대 한 대다수의 사용 사례가 정확히 T
이 무엇인지 신경 씁니다. 그렇지 않은 경우 정확히 Action<T>
을 사용 하시겠습니까? (전화 사이트에서 T
을 걱정하지 않는 경우는 드물지만 희소식이므로이 기능을 실제로 구현하는지 여부를 고려하는 것이 좋습니다.
Github [link] (https://github.com/facebook/hhvm/issues/3183)에서 desugaring에 대한 귀하의 의견에 따라 동작이 완전히 이해됩니다. 그러나 액션
나는 Hack의 전문가는 아니지만, 당신의 설정이'Action'을 monomorphic 클래스에서 상속받는 것과 같다고 말합니다.'ActionBase'는'Action <*>'에 의해 사용 된 인터페이스를 노출시킵니다. 해당 코드를 디자인하는 경우 액션 클래스를 리팩토링 할 수 있습니다. – didierc