Я согласен с Берги в использовании Date, но его решение было немного излишним для моего использования. Я просто хотел, чтобы мои анимированные часы (цифровые и аналоговые SVG) обновлялись на втором и не переполнялись или выполнялись, создавая очевидные скачки в обновлениях часов. Вот фрагмент кода, который я ввел в мои функции обновления часов:
var milliseconds = now.getMilliseconds();
var newTimeout = 1000 - milliseconds;
this.timeoutVariable = setTimeout((function(thisObj) { return function() { thisObj.update(); } })(this), newTimeout);
Он просто вычисляет время дельта до следующего даже второго и устанавливает тайм-аут этой дельта. Это синхронизирует все мои объекты часов со вторым. Надеюсь, это полезно.
Попробуйте этот странный трюк:
g = oa -> Math.max(0, f.apply(oa.map(a -> a)));
// ^----------^
Сопоставление типа необязательного, как это, позволяет компилятору «отличать» тип необязательного до согласованного типа.
Это имеет недостаток в создании нового экземпляра Optional
.
Но, конечно, я задал этот вопрос , который размышляет, действительно ли это то, что должно быть разрешено спецификацией или ошибкой.
Лично я не считаю ваше «лучшее до сих пор» особенно вопиющим. Конечно, это зависит от того, как выглядит реальный код.
Решение изменит вашу сигнатуру вашего интерфейса:
double apply(Optional<? extends A> a);
Рассмотрим, если ваш интерфейс просто:
double apply(A a);
Тогда никогда ошибка не будет [. g3]
Это потому, что Double
назначается Object
. Компилятор автоматически адаптирует тип. Это означает, что на самом деле интерфейс:
double apply(? extends A a);
Итак, что вам нужно, это позволить вашему интерфейсу использовать эту способность адаптации.
func(Number)
может принимать параметр Double
в качестве параметра.
func(Optional<Number>)
также должен принять Optional<Double>
.
Итак, вы должны добавить ? extends
на свою интуицию.
В общем, я нахожу, что вывод типа для суперграфов в Java является кошмаром. Есть много ошибок компилятора, и обычно трудно объяснить, почему компилятор отклонит определенный синтаксис, а не другие.
Тем не менее, вы можете обойти это хакерским способом, добавив f
в тип Func<Double>
. Это не совсем безопасный бросок; если f
имеет какое-либо состояние, мы можем предположить, что нижняя граница на f
равна Double
, когда на самом деле это может быть Number
или Object
. С броском вы не несете штраф за выполнение решения, предоставленного @AndyTurner, но неконтролируемые роли также не являются вашим другом.
public double compute(Func<? super Double> f) {
// Sometimes amend the function to do something slightly different
Func<? super Double> g = f;
if (someCondition())
g = oa -> Math.max(0, (((Func<Double>) f)).apply(oa));
return g.apply(Optional.of(3.14)) + g.apply(Optional.empty());
}
В целом, я бы рассмотрел решение, которое вы представили в вопросе быть лучшим решением проблемы. Это немного более подробный, но компилятор должен иметь возможность оптимизировать код. Вы не теряете безопасность времени компиляции с помощью непроверенных бросков, и вы не вводите дефрагментацию времени выполнения из-за создания дополнительных экземпляров Optional
.
Optional
. В случаях, когда у нас нет API-интерфейса преобразования, я задаюсь вопросом, существует ли более общий i> шаблон;) – flakes 14 July 2018 в 02:08