Более-высокие-kinded дженерики в Java

Ваше утверждение if/else использует больше эквивалентных условий, чем просто TouchPhase.Moved.

Похоже, что TouchPhases являются следующими.

TouchPhase.Began вместо Input.GetMouseButtonDown(0)

TouchPhase.Moved вместо Input.GetMouseButton(0)

TouchPhase.Ended вместо финального else

PS: дал тот же ответ на UnityAnswers

Итак, это может выглядеть так:

void Update()
{
    if (Input.touchCount > 0)
    {
        Touch touch = Input.GetTouch(0);

        if (touch.phase == TouchPhase.Began)
        {
            deltaRotation = 0f;
            previousRotation = angleBetweenPoints(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition));
        }
        else if (touch.phase == TouchPhase.Moved)
        {
            currentRotation = angleBetweenPoints(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition));
            deltaRotation = Mathf.DeltaAngle(currentRotation, previousRotation);
            if (Mathf.Abs(deltaRotation) > deltaLimit)
            {
                deltaRotation = deltaLimit * Mathf.Sign(deltaRotation);
            }
            previousRotation = currentRotation;
            transform.Rotate(Vector3.back * Time.deltaTime, deltaRotation);
        }
        else if (touch.phase == TouchPhase.Ended)
        {
            transform.Rotate(Vector3.back * Time.deltaTime, deltaRotation);
            deltaRotation = Mathf.Lerp(deltaRotation, 0, deltaReduce * Time.deltaTime);
        }
    }
}
31
задан Ben Lings 14 January 2010 в 19:09
поделиться

4 ответа

Я думаю, что то, что вы пытаетесь сделать, просто не поддерживается универсальными шаблонами Java. Более простой случай

public class Foo<T> {
    public T<String> bar() { return null; }
}

также не компилируется с использованием javac.

Поскольку Java не знает во время компиляции, что такое T , он не может гарантировать, что T вообще имеет смысл. Например, если вы создали Foo , bar будет иметь подпись

public BufferedImage<String> bar()

, что бессмысленно. Поскольку нет механизма, который заставлял бы вас создавать экземпляры Foo только с помощью общих T , он отказывается компилироваться.

26
ответ дан 27 November 2019 в 22:14
поделиться

Чтобы передать параметр типа, определение типа должно объявить, что оно его принимает (это должно быть универсальное ). Очевидно, ваш F не является универсальным типом.

ОБНОВЛЕНИЕ: в строке

F<Fix<F>> in;

объявляется переменная типа F , которая принимает параметр типа, значение которого равно Исправление , которое само принимает параметр типа, значение которого равно F . F даже не определен в вашем примере. Я думаю, вы можете захотеть

Fix<F> in;

. Это даст вам переменную типа Fix (тип, который вы определили в своем примере), которому вы передаете параметр типа со значением F . Поскольку Исправление определено для принятия параметра типа, это работает.

ОБНОВЛЕНИЕ 2: Перечитайте заголовок, и теперь я думаю, что вы, возможно, пытаетесь сделать что-то похожее на подход, представленный в «На пути к равным правам для высокородных типов» (предупреждение в формате PDF). В таком случае Java не поддерживает это, но вы можете попробовать Scala.

5
ответ дан 27 November 2019 в 22:14
поделиться

Похоже, вам может понадобиться что-то вроде:

public class Fix<F extends Fix<F>> {
    private F in;
}

(См. Класс Enum и вопросы о его обобщениях.)

0
ответ дан 27 November 2019 в 22:14
поделиться

Возможно, вы можете попробовать Scala, который является функциональный язык, работающий на JVM, который поддерживает дженерики более высокого порядка.


[EDIT by Rahul G ]

Вот как ваш конкретный пример примерно переводится на Scala:

trait Expr[+A]

trait FixExpr {
  val in: Expr[FixExpr]
}

trait Fix[F[_]] {
  val in: F[Fix[F]]
}
25
ответ дан 27 November 2019 в 22:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: