gpt4 book ai didi

java - 如何将java泛型翻译成Delphi

转载 作者:行者123 更新时间:2023-12-02 19:55:23 25 4
gpt4 key购买 nike

我正在将 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,它接受名为mappingfunction作为参数,但我不确定如何对此进行建模。

对于上下文,这是完整的代码:

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 的类型。其中包括 TObject 以及层次结构中位于它们之间的任何其他类型。

类似地,to 将使用mapping 的结果来获取U 类型的值。 Mapping 不必声明为专门返回 U,但无论它返回什么类型,都需要可分配给 U

无法在 Delphi 中表达这些约束。您能做的最好的事情就是请求一个使用字面意思 TU 的函数类型:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com