[英]Why do I need to add the type here, and is there a better way?
以下代碼無法編譯,
Validation<String, AdRequest> validateTrackingRequest(final AdRequest request) {
return request.getTracking().stream()
.filter(tracker -> tracker.url().length() > URL_CHAR_LIMIT).findAny()
.map(tracker ->
Validation.invalid("Tracking URL for event " + tracker.type() + " exceeds "
+ URL_CHAR_LIMIT + " character limit: " + tracker.url()))
.orElse(Validation.valid(request));
}
與錯誤消息,
Incompatible types. Required: Validation<String, AdRequest>. Found Validation<String, Object>.
嘗試一下,我發現在調用map
之前添加這個奇怪的語法解決了這個問題:
.<Validation<String, AdRequest>>map(tracker ->
(之前我見過其他人這樣做過。)
這是什么語法?
我知道這是因為Validation.invalid
的底層機制必須基於通用Object
,因此需要某種類型的強制轉換。 所以也許這種語法是“演員”。
但是,有沒有更好的方式來寫我正在做的事情?
(這是javaslang
aka vavr
的驗證庫。)
它被稱為帶有顯式類型參數的方法調用。 你可以使用一種不那么“怪異”的語法:
Validation.<String, AdRequest>invalid(...)
問題在於如何定義Validation.invalid
方法以及在其中調用的上下文。
static <E, T> Validation<E, T> invalid(E error)
由於map
不關心結果的類型,因此無法隱式確定第二通用參數T
// no context
Validation<String, Object> v1 = Validation.invalid("error");
// the context set explicitly
Validation<String, AdRequest> v2 = Validation.<String, AdRequest>invalid("error");
// the type is determined by the context implicitly
Validation<String, AdRequest> v3 = Validation.invalid("error");
要弄清楚類型,應該存在上下文。 Optional.map
不會為您提供此上下文。 它適用於您傳遞的任何結果類型R
:
// v1 = Validation<String, Object>
Optional<Validation<String, Object>> o1 = ofNullable(null).map(i -> v1);
// v2 = Validation<String, AdRequest>
Optional<Validation<String, AdRequest>> o2 = ofNullable(null).map(i -> v2);
它將根據您提供的類型返回一個通用實例。 您正在提供Validation<String, Object>
對象,因此您將獲得map(Function<..., Validation<String, Object>>)
,這會混淆orElse
與返回類型相矛盾。
這是一個品味問題,但我會把一些東西放到變量中:
Validation<String, AdRequest> validateTrackingRequest(AdRequest request) {
Validation<String, AdRequest> valid = Validation.valid(request);
Function<Tracker, Validation<String, AdRequest>> mapper = tracker -> Validation.invalid(...);
Predicate<Tracker> predicate = tracker -> ...;
return request.getTracking().stream().filter(predicate).findAny().map(mapper).orElse(valid);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.