先看乙個傳統的隱式轉換方法實現
/** 上下文界定
* author: leisu
* date 2018/8/15 17:36
*/implicit def agecondition(person: poet) = person.age > 18
val cb = new contextbounds
val list: list[poet] = list(new poet("李白", 35),
new poet("白居易", 19),
new poet("蘇軾", 34),
new poet("辛棄疾", 17),
new poet("杜甫", 21),
new poet("張良", 18)
) println(cb.dofilter(list))
}class contextbounds
/** * 定義乙個condition特質,包含condition方法,混入此特質的類,可以使用condition進行篩選
* * @tparam t 協變
*/trait condition[+t]
/** * 詩人類
*/case class poet(val name: string, val age: int) extends condition[poet]
可以看到,隱式傳入的引數是: agecondition,這是乙個def方法,型別為(poet => boolean),是((t<: condition)=> boolean)的子類,所以可以隱式傳入。在呼叫時,只顯式傳入類第乙個引數,具體呼叫為:cb.dofilter(list),就可以成功。
呼叫後的輸出為:
list(poet(李白,35), poet(白居易,19), poet(蘇軾,34), poet(杜甫,21))
起到了過濾的效果
我們對上面對例子進行初步改變
/** 上下文界定
* author: leisu
* date 2018/8/15 17:36
*/implicit def agecondition(person: poet) = person.age > 18
val cb = new contextbounds
val list: list[poet] = list(new poet("李白", 35),
new poet("白居易", 19),
new poet("蘇軾", 34),
new poet("辛棄疾", 17),
new poet("杜甫", 21),
new poet("張良", 18)
) println(cb.dofilter(list))
}class contextbounds
/** * 定義乙個condition特質,包含condition方法,混入此特質的類,可以使用condition進行篩選
* * @tparam t 協變
*/trait condition[+t]
/** * 詩人類
*/case class poet(val name: string, val age: int) extends condition[poet]
在這個改動版本中,我們其他地方都沒變,只有class contextbounds類的 dofilter方法進行類變化:
def dofilter[t <: condition[t]](data: list[t])(implicit condition: t => boolean): list[t] =
data.filter(_.judge(implicitly[t => boolean])) //*** 注意這裡的改動
def implicitly[t](implicit t: t) = t它的作用只是將乙個隱式轉換傳入作用域內,好讓下面的implicitly[t => boolean]能查詢到已定義好的隱式轉換。
上面例子中,我們發現了:方法定義的隱式引數入參名不重要,因為函式實體內不直接呼叫此引數名,它只是乙個宣告。這就給了我們再次優化的可能。scala對引入隱式型別有乙個新的語法,也就是:上下文界定。例子如下
/**
* 封裝原方法的類,可以看到這裡有乙個型別引數u,並且我們的方法帶上型別引數,可用度更加廣了
*/abstract class myfunctionclass[u]
/** 上下文界定
* author: leisu
* date 2018/8/15 17:36
*//**** 改動一: 這裡封裝了下原先的方法,把它放到了myfunctionclass類之下
* 因為上下文引入必須是帶有乙個型別引數的類的例項
* 雖然原先的方法時function1[poet, boolean]的例項,但無法再給它加其他型別引數,所以封裝*/
implicit val agecondition: myfunctionclass[poet] = new myfunctionclass[poet] ;
val cb = new contextbounds
val list: list[poet] = list(new poet("李白", 35),
new poet("白居易", 19),
new poet("蘇軾", 34),
new poet("辛棄疾", 17),
new poet("杜甫", 21),
new poet("張良", 18)
) println("完全上下界實現:" + cb.dofilter(list))
}class contextbounds
/** * 定義乙個condition特質,包含condition方法,混入此特質的類,可以使用condition進行篩選
* * @tparam t 協變
*/trait condition[t]
/** * 詩人類
*/case class poet(val name: string, val age: int) extends condition[poet]
這裡我們有幾個改動:
定義了乙個新類: myfunctionclass[t],其中含有乙個型別引數t。這個類是為了封裝我們之前定義的(poet => boolean)方法。之所以定義這個類,是與上下文界定的語法有關的: 上下文界定語法要求傳入有乙個型別引數的類的例項。雖然說(poet => boolean)也是function[poet, boolean]的例項,但是它沒法再有乙個型別引數,所以我這裡採用了封裝的思想,專門定義了myfunctionclass類,用來傳參。
在object contextbounds中,我宣告了這個類的實現:implicit val agecondition: myfunctionclass[poet],並且定義它為隱式轉換。這樣,這個agecondition就可以載入到其他需要此型別的隱式引數中了。
對於原先傳入隱式引數的dofilter方法,我們現在做如下定義:
def dofilter[t: myfunctionclass](data: list[t]): list[t] = data.filter(implicitly[myfunctionclass[t]].myfunction(_))這裡可以看到並沒有像之前那樣,再方法體上直接傳入隱式入參(implicit condition ...), 那是如何生效的呢?注意看之前的型別引數那裡,這裡的定義方法為[t: myfunctionclass],這一步宣告有兩個效果:
這樣整個通過上下文界定實現傳入隱式引數的功能就全部實現。最後執行的效果為:
完全上下界實現:list(poet(李白,35), poet(白居易,19), poet(蘇軾,34), poet(杜甫,21))
可以看到與之前的結果相同 上下文 上下文棧
全域性 函式 區域性 在執行全域性 前將window確定為全域性執行上下文 對全域性資料進行預處理 var定義的全域性變數 undefined,新增為window的屬性 function宣告的全域性函式 賦值 fun 新增為window的方法 this 賦值 window 開始執行全域性 在呼叫函式...
中斷上下文 程序上下文
在學習與作業系統相關的知識時候,我們經常遇到程序上下文 中斷上下文,看似熟悉又感覺不是特別清晰。這裡我們從如下幾個方面進行描述。上下文是從英文中context翻譯過來的,指的是一種環境。上下文我們看起來不怎麼熟悉,但是我們可以看context的中文翻譯,或者我們能更加的情形些。context n 語...
全域性上下文與上下文
全域性上下文由main函式載入系統的主架構和主事件迴圈和全域性資料構成。是上帝創造世界時,建立的基礎事物。萬物之始,大道至簡,衍化至繁。全域性上下文代表著程式執行所需要的基礎資源。是程式執行的基礎。全域性上下文的特徵是在程式執行期間常駐記憶體。全域性上下文的生命週期和應用程式的生命週期相同。與應用程...