- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将 Nat Pryce 的 Maybe
类翻译成 Delphi。
以下是一些背景:http://www.natpryce.com/articles/000776.html
大部分都很简单,但是......
我如何将这个声明从 Java 翻译成 Delphi?
public abstract <U> Maybe<U> to(Function<? super T, ? extends U> mapping);
它是一个抽象虚拟函数&to
,它接受名为mapping
的function
作为参数,但我不确定如何对此进行建模。
对于上下文,这是完整的代码:
package com.natpryce.maybe;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import java.util.Collections;
import java.util.Iterator;
public abstract class Maybe<T> implements Iterable<T> {
public abstract boolean isKnown();
public abstract T otherwise(T defaultValue);
public abstract Maybe<T> otherwise(Maybe<T> maybeDefaultValue);
public abstract <U> Maybe<U> to(Function<? super T, ? extends U> mapping);
public abstract Maybe<Boolean> query(Predicate<? super T> mapping);
public static <T> Maybe<T> unknown() {
return new Maybe<T>() {
@Override
public boolean isKnown() {
return false;
}
public Iterator<T> iterator() {
return Collections.<T>emptyList().iterator();
}
@Override
public T otherwise(T defaultValue) {
return defaultValue;
}
@Override
public Maybe<T> otherwise(Maybe<T> maybeDefaultValue) {
return maybeDefaultValue;
}
@Override
public <U> Maybe<U> to(Function<? super T, ? extends U> mapping) {
return unknown();
}
@Override
public Maybe<Boolean> query(Predicate<? super T> mapping) {
return unknown();
}
@Override
public String toString() {
return "unknown";
}
@Override
@SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"})
public boolean equals(Object obj) {
return false;
}
@Override
public int hashCode() {
return 0;
}
};
}
public static <T> Maybe<T> definitely(final T theValue) {
return new DefiniteValue<T>(theValue);
}
private static class DefiniteValue<T> extends Maybe<T> {
private final T theValue;
public DefiniteValue(T theValue) {
this.theValue = theValue;
}
@Override
public boolean isKnown() {
return true;
}
public Iterator<T> iterator() {
return Collections.singleton(theValue).iterator();
}
@Override
public T otherwise(T defaultValue) {
return theValue;
}
@Override
public Maybe<T> otherwise(Maybe<T> maybeDefaultValue) {
return this;
}
@Override
public <U> Maybe<U> to(Function<? super T, ? extends U> mapping) {
return definitely(mapping.apply(theValue));
}
@Override
public Maybe<Boolean> query(Predicate<? super T> mapping) {
return definitely(mapping.apply(theValue));
}
@Override
public String toString() {
return "definitely " + theValue.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DefiniteValue<?> that = (DefiniteValue<?>) o;
return theValue.equals(that.theValue);
}
@Override
public int hashCode() {
return theValue.hashCode();
}
}
}
最佳答案
Java 代码利用了参数类型的协变和逆变。 to
的参数应该是一个带有一个参数的函数。参数的类型可以是 T
或 T
的任何父类(super class)型。该函数应返回 U
类型的值或 U
的任何子类型。
to
函数将调用 mapping
并向其传递当前持有的 T
类型的值(如果它持有任何值)根本),因此 mapping
的参数类型需要是可以分配给 T
的类型。其中包括 T
、Object
以及层次结构中位于它们之间的任何其他类型。
类似地,to
将使用mapping
的结果来获取U
类型的值。 Mapping
不必声明为专门返回 U
,但无论它返回什么类型,都需要可分配给 U
。
无法在 Delphi 中表达这些约束。您能做的最好的事情就是请求一个使用字面意思 T
和 U
的函数类型:
function &to<U>(mapping: TFunc<T, U>): Maybe<U>;
您也许能够通过引入另一个类型参数来表达对U
的约束:
function &to<U: class; V: U>(mapping: TFunc<T, V>): Maybe<U>;
不过,我不知道类型参数是否可以用作同一参数列表中其他参数的约束。我也不确定编译器能否在该上下文中推断出 V
的值,因此调用 to
会很麻烦。
另一方面,如果虚拟方法不能有新的泛型参数(例如 U
),那么约束就根本不重要,因为您无法首先声明该方法.
但是,根据引用实现,Maybe
只有两种具体实现,因此一种可能性是将 to
实现为非虚拟 函数,然后手动检查运行时类型。这不会很漂亮。像这样的事情:
if Self is TUnknown<T> then
Result := unknown<U>
else
Result := definitely(mapping(TDefiniteValue<T>(Self).value));
关于java - 如何将java泛型翻译成Delphi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19160740/
我是一名优秀的程序员,十分优秀!