【发布时间】:2013-10-03 13:39:08
【问题描述】:
我正在将 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();
}
}
}
【问题讨论】:
-
您可以将此类用作 Oasis 专辑标题生成器
-
你可以看看Spring.Nullable<T>。
-
顺便说一句,上面的代码避免的真正问题是 Java 独有的,Delphi 中的习惯用法是在调用 X.Something 之前检查
if Assigned(X)那可能是空的。我认为 java 令人作呕的异常模型和语义(例如,在 Java 代码库中是否见过连续 30 个检查异常捕获的块?)是上述代码和类型以及博客文章的部分原因。 -
@WarrenP,我知道,我想要一些关于如何解决 Delphi 缺乏协变等问题的练习。尽管它们看起来与 java、C# 和 Delphi 中泛型的
feel很相似。 Java 的泛型感觉很棒,但是还有 type erasure sigh. -
本质上,C# 和 Java 中涉及协方差的大多数问题最好在 Delphi 中以另一种方式解决,通常根本不需要泛型。换句话说,回到第 1 格并编写您自己的手卷解决方案,没有泛型。
标签: java delphi generics delphi-xe2