簡體   English   中英

為什么我需要在這里添加類型,有更好的方法嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM