12.4.1 自定義查詢表示式
原則上,我們可以使用查詢處理任何型別,只要它提供了繫結操作。這是函式式程式設計中這類函式的標準名稱,像上一節型別簽名所展示的。從技術角度來講,我們需要實現一些方法,在把查詢表示式轉換為標準的函式呼叫,由 c# 編譯器所使用。我們將為 12.6 節中的 option的型別實現這些方法,該型別沒有實現 ienumerable,所以,不能使用標準查詢運算子。
我們首先考慮一下,查詢應用到選項型別,是什麼意思。清單 12.15 有兩個查詢,左邊的處理列表,右邊的處理選項型別。我們將使用兩個簡單的函式來提供輸入:readintlist 函式讀取整數列表(型別為 list),tryreadint 返回選項值(型別為 option)。
清單 12.15 對列表和選項值使用查詢 (c#)
var list =
from n in readintlist()
from m in readintlist()
select n * m;
var option =
from n in tryreadint()
from m in tryreadint()
select n * m;
除了處理的資料型別不同之外,查詢完全相同,因此,它們使用不同的查詢運算子實現。兩者都讀不同的輸入,並返回輸入整數的積。表 12.1 給出了樣本輸入和結果。
表 12.1 對於可能的不同輸入,由使用列表和選項值的查詢所產生的結果
type of values
input #1
input #2
output
lists
options
options
options
[2; 3]
some(2)
some(3)
none
[10; 100]
some(10)
none
not required
[20; 200; 30; 300]
some(20)
none
none
對於列表,查詢執行交叉聯接運算(可以想象成 f# 序列表示式中的兩個巢狀for 迴圈),會產生乙個序列,由輸入值的每種組合條目所組成;對於選項值,有三種可能性。
■當第乙個輸入是值時,需要讀第二個。然後,根據第二個輸入的不同,有以下兩種情況:
— 如果第二個輸入也是值,則結果是 some 值,包含的結果是積。
— 如果第二個輸入是 none,由於沒有值相乘,因此,查詢返回 none。
■當第乙個輸入為 none 時,我們知道,結果無需考慮第二輸入。整個查詢延遲執行,所以,不必去讀第二輸入:tryreadint 函式只呼叫一次。
可以發現,查詢表示式提供了一種簡便的方法,處理選項值。清單 12.15 無疑要比我們在第六章看到的等價**,容易寫(和讀),那時,我們顯式地使用了高階函式。在本章的後面我們將會看到,實現所有必要的查詢運算子;不過,現在,我們還是先看一下在 f# 中的類似語法。
lamda表示式之自定義
package com.lyon.controller public class testlamda public static void main string args ilike like3 new like3 like3.lamda 5.匿名內部類,沒有類名稱,必須借助介面或者父類 ilik...
自定義Lamda表示式作為篩選條件
var ints new int var r ints.where i i 5 i 7 i 3 要a實 現?的?表 達?式?創 建 參?數y i var parameter expression.parameter typeof int i 創 建 表 達?式?i 5 var con1 expres...
用自定義的棧實現算術表示式(字尾表示式)求值
include include using namespace std define max 88 luosansui s sequential stack 構建乙個棧的資料型別 struct stack 定義運算元優先順序 void priority char singlesym,int p 判斷...