[英]Type constraint on input function parameter in Scala
我正在嘗試創建一個更高階的 function,它具有輸入 function 接受的參數類型的上限。
一個演示問題的幼稚嘗試的玩具示例:
class A
class B extends A
def AFunc(f: A => Unit): Unit = {}
AFunc((b: B) => {})
//<console>:14: error: type mismatch;
// found : B => Unit
// required: A => Unit
// AFunc((b: B) => {})
我認為這不起作用,因為函數的參數是逆變的,所以 B => Unit 是 A => Unit 的超類型。
可以讓它與多態函數一起工作,如下所示:
class A
class B extends A
def AFunc[T <: A](f: T => Unit): Unit = {}
AFunc[B]((b: B) => {})
這個解決方案的缺點是要求調用者知道傳遞函數參數的確切類型,盡管所有 AFunc 關心的類型是它是 A 的子類型。
是否有一種類型安全的方法來強制類型約束而不顯式傳遞類型?
您的問題不是由於語言結構的限制,而是概念性的。 函數在其 arguments 中是逆變的是有原因的。
如果我們將您的代碼稍微擴展為以下情況,您會期望發生什么:
class A
class B extends A
def AFunc(f: A => Unit): Unit = {
f(new A) // let's use the function f
}
AFunc((b: B) => {}) // ???
這將如何編譯? 方法AFunc
顯然需要一種方法來處理A
值,但您只為它提供了一種處理這些值的一個子集(= B
類型的值)的方法。
當然,您可以按照您的方式使您的方法具有多態性,順便說一句,您甚至不需要在調用站點指定參數類型,因為它會被推斷出來。 但是,這不是“解決方案”。 這只是另一回事。 現在,您的方法不是說“我需要一個處理A
類型值的 function ”,而是說“我需要一個處理A
的一個特定子類型的 function ,但我對您決定的任何子類型都可以”。
所以,就像 StackOverflow 上經常發生的那樣,我不得不問你——你想要實現什么? 您的方法AFunc
是要處理所有類型的A
,還是一次只處理一個特定的子類型?
如果是后者,則使用上限(如您所做的那樣)進行參數化應該沒問題。 如果您決定不在調用站點指定類型,請小心推斷,因為有時您的代碼可能會編譯只是因為編譯器推斷出與您預期不同的內容(我從您問題中的評論中看到您已經發現了這種行為)。 但是,如果參數方法確實是您需要的,那么我不明白為什么在調用站點指定類型會成為問題。
盡管所有 AFunc 關心的類型是它是 A 的子類型。
當然, AFunc
不在乎。 但是來電者確實如此。 我的意思是,有人必須關心,對吧? :) 同樣,如果不了解您正在解決的實際問題,就很難繼續討論,但如果您想提供更多詳細信息,我很樂意提供幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.