成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

JS語(yǔ)法也可以有C#的switch表達(dá)式

瀏覽:8日期:2022-06-09 15:19:28
目錄
  • 正文
  • 新的約束
  • when 函數(shù)寫(xiě)法
  • 分算等級(jí)”測(cè)試
    • 測(cè)試問(wèn)題
    • 升級(jí)成 TypeScript

正文

于 C/Java 語(yǔ)系的語(yǔ)言,都有 switch 語(yǔ)法。switch 語(yǔ)法用于多分支是一個(gè)標(biāo)準(zhǔn)的用法,但這個(gè)分支語(yǔ)法的各分支之間存在穿透性,所以需要 break 來(lái)切斷邏輯,這也成為 switch 語(yǔ)法中最重要的一個(gè)替在缺陷來(lái)源。此外,由于 switch 語(yǔ)句中各 case 的代碼是在同一個(gè)作用域中,也會(huì)對(duì)代碼造成一些不便。

C# 8.0 引入了 switch 表達(dá)式。C# 的 switch 表達(dá)式有著非常豐富的語(yǔ)法元素,可以和模式匹配和解構(gòu)等語(yǔ)法元素協(xié)同工作 —— 這些都不在這里細(xì)說(shuō),但是對(duì)傳統(tǒng)的 switch 語(yǔ)句 進(jìn)行了一些改進(jìn):

  • 通過(guò)箭頭 (=>) 標(biāo)記處理了 case 和語(yǔ)句之間的一對(duì)一關(guān)系,不需要 break,不再穿透;
  • 作為表達(dá)式,可以而且必須返回值;

新的約束

  • switch 表達(dá)式一定要詳盡(邏輯一定會(huì)走進(jìn)某一個(gè) case,可以通過(guò)棄元模式兜底),否則可能會(huì)在運(yùn)行時(shí)引發(fā)異常。

在 C# 8.0 發(fā)布的同年,Java 12 也發(fā)布并引入了 switch 表達(dá)式預(yù)覽。Java 的 switch 表達(dá)式實(shí)現(xiàn)比較簡(jiǎn)單,就是 switch 語(yǔ)句到 switch 表達(dá)式的直接轉(zhuǎn)換,僅支持等值匹配。直到 2023 年 3 月 Java 20 發(fā)布,switch 表達(dá)式才開(kāi)始支持模式匹配。相比之下,Kotlin 的 when 表達(dá)式走在了前面。

在這個(gè)問(wèn)題上 JavaScript 似乎走在了后面,不過(guò)在語(yǔ)言提供 switch 表達(dá)式之前,我們可以嘗試自己造個(gè)輪子。

思路當(dāng)然是參考策略模式。假設(shè)有一個(gè)列表,這個(gè)列表里的每個(gè)元素都包含了兩個(gè)因素:第一個(gè)用于判斷是否命中,第二個(gè)是個(gè)函數(shù),得到一個(gè)計(jì)算結(jié)果。然后寫(xiě)一個(gè)循環(huán)遍歷列表的每個(gè)元素,一旦某個(gè)元素命中,就執(zhí)行元素?cái)y帶的函數(shù)獲得結(jié)果,中斷循環(huán),返回結(jié)果。如果列表的最后一個(gè)元素必定命中,那么這個(gè)列表就是“詳盡”的。

when 函數(shù)寫(xiě)法

那么這個(gè) when 函數(shù)可能會(huì)這樣寫(xiě)(switch 是關(guān)鍵字,所以使用 when 來(lái)作為函數(shù)名):

// JS
function when(value, ...cases) {
    for (const { is, run } of cases) {
if (is(value)) {
    return run(value);
}
    }
    throw new Error("非詳盡");
}

這里我們假設(shè)每個(gè)情況 (case) 都含有 is 方法用于判斷是否命中,用 run 方法保存命中后需要執(zhí)行的操作。

分算等級(jí)”測(cè)試

相應(yīng)地,我們可以經(jīng)典的“拿分算等級(jí)”來(lái)進(jìn)行測(cè)試:

// JS
function calcGrade(score) {
    return when(
score,
{ is: v => v >= 0 && v < 80, run: v => `不合格 (${v})` },
{ is: v => v >= 80 && v < 100, run: v => `合格 (${v})` },
{ is: v => v == 100, run: v => `滿分 (${v})` },
{ is: _ => true, run: v => `無(wú)效 (${v})` },
    );
}
for (let i = 0; i < 50; i++) {
    const v = 70 + ~~(Math.random() * 35);
    console.log(calcGrade(v));
}

在 calcGrade 實(shí)現(xiàn)中 when 的 case 列表最后一項(xiàng)采用了“永真”斷言,所以走到這一項(xiàng)的時(shí)候一定會(huì)命中,從邏輯上來(lái)永遠(yuǎn)不會(huì)觸發(fā) Error。如果是非“詳盡”的情況列表,就有可能觸發(fā) Error。

測(cè)試問(wèn)題

不過(guò)現(xiàn)在從測(cè)試代碼中就發(fā)現(xiàn)了兩個(gè)問(wèn)題:

  • is 斷言是采用函數(shù)的形式,不能簡(jiǎn)單地直接按值匹配;
  • 從調(diào)用形式上來(lái)說(shuō),score 和后面的 case 元素是同級(jí)的,形式上區(qū)分不明顯;
  • 每次都要寫(xiě) is 和 run,條件多了寫(xiě)起來(lái)也煩。

繼續(xù)改進(jìn) ——

// JS
function when(value) {
    // when 的參數(shù)先給 switch 的值
    // 返回一個(gè)函數(shù)來(lái)處理分支匹配 ②
    return function (...cases) {
for (const [is, run] of cases) {
// ^^^^^^^^^ 從對(duì)象改為元組(數(shù)組)③
    if (value === is || (typeof is == "function" && is(value))) {
//    ^^^^^^ 精確判斷 ①
//       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 斷言函數(shù)判斷
return  run(value);
//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 可指定行為(函數(shù))
    }
}
throw new Error("非詳盡");
    };
}
function calcGrade(score) {
    return when(score)(
// ^^^^^^^^^^^ 這里返回的是匹配處理的函數(shù)
[v => v >= 0 && v < 80, v => `不合格 (${v})`],
[v => v >= 80 && v < 100, v => `合格 (${v})`],
[100, () => "滿分 (100)"],
//       ^^^ 可以指定匹配的值
//    ^^ 計(jì)算不需要參數(shù),可以不聲明
[_ => true, v => `無(wú)效 (${v})`],
//       ^^^^^^^^^ 兜底的永真斷言
    );
}

為什么兜底斷言必須使用一個(gè)函數(shù)呢?因?yàn)?nbsp;true 值也有可能是對(duì)應(yīng)一種預(yù)想的分支情況。由于這個(gè) when 是通過(guò)語(yǔ)義來(lái)實(shí)現(xiàn)而不是通過(guò)語(yǔ)法來(lái)實(shí)現(xiàn)的,所以這里沒(méi)辦法定義一個(gè)安全的兜底斷言語(yǔ)法,只有用斷言函數(shù)會(huì)相對(duì)安全。

升級(jí)成 TypeScript

至此為止我們已經(jīng)基本實(shí)現(xiàn)了 switch 表達(dá)式 (when),把它升級(jí)成 TypeScript

// TypeScript
type CaseCondition<T> = T extends Function ? never : ((t: T) => boolean) | T
type Case<T, R> = [CaseCondition<T>, (t: T) => R];
function when<T>(value: T): <R>(...cases: Case<T, R>[]) => R {
    return function<R>(...cases: Case<T, R>[]): R {
for (const [is, run] of cases) {
    if (value === is || (typeof is == "function" && is(value))) {
return run(value);
    }
}
throw new Error("非詳盡");
    };
}
function calcGrade(score: number) {
    return when(score)(
[v => v >= 0 && v < 80, v => `不合格 (${v})`],
[v => v >= 80 && v < 100, v => `合格 (${v})`],
[100, () => "滿分 (100)"],
[_ => true, v => `無(wú)效 (${v})`],
    );
}

這段代碼當(dāng)然可以直接用,但是如果使用 npm 可能會(huì)更方便一點(diǎn):

npm install @jamesfancy/when
// TypeScript
import { when } from "@jamesfancy/when";
function calcGrade(score: number) {
    return when(score)(
[v => v >= 0 && v < 80, v => `不合格 (${v})`],
[v => v >= 80 && v < 100, v => `合格 (${v})`],
[100, () => "滿分 (100)"],
[_ => true, v => `無(wú)效 (${v})`],
    );
}

以上就是JS語(yǔ)法也可以有C# 的switch表達(dá)式的詳細(xì)內(nèi)容,更多關(guān)于JS語(yǔ)法C# switch表達(dá)式的資料請(qǐng)關(guān)注其它相關(guān)文章!

標(biāo)簽: JavaScript
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
国产精品永久| 欧美日韩你懂的| 一本到不卡精品视频在线观看 | 欧美不卡一卡二卡免费版| 欧美二区三区91| 男男成人高潮片免费网站| 一区精品在线| 国产精品美女久久久久aⅴ国产馆| 成人av网站免费| 日韩精品中文字幕一区二区三区| 国产综合色精品一区二区三区| 欧美三级午夜理伦三级中视频| 男女视频一区二区| 91黄色免费观看| 蜜桃在线一区二区三区| 日本久久一区二区三区| 免费观看91视频大全| 欧美视频三区在线播放| 韩国女主播一区二区三区| 91.xcao| 国产大片一区二区| 911精品产国品一二三产区 | 狠狠色噜噜狠狠狠狠色吗综合 | 青青草国产精品97视觉盛宴| 色婷婷亚洲精品| 美脚の诱脚舐め脚责91 | 最新亚洲视频| 亚洲欧美另类小说| 亚洲精品一级| 亚洲欧美偷拍卡通变态| 国产精品区一区| 三级一区在线视频先锋| 91国偷自产一区二区开放时间 | 亚洲视频每日更新| 亚洲二区免费| 亚洲人成电影网站色mp4| 亚洲人体大胆视频| 亚洲一区二区三区四区五区黄 | 国产色婷婷亚洲99精品小说| 欧美激情自拍| 亚洲欧美综合在线精品| 宅男噜噜噜66一区二区| 婷婷综合在线观看| 欧美亚洲国产一区二区三区| 精品午夜一区二区三区在线观看 | 亚洲欧美色综合| 国产精品日韩精品欧美精品| 午夜a成v人精品| 欧美日韩国产bt| 国产成人一区在线| 久久综合久久综合九色| 欧美午夜电影在线观看 | 精品不卡视频| 亚洲观看高清完整版在线观看| 噜噜噜91成人网| 欧美a一区二区| 欧美精品一二三四| 豆国产96在线|亚洲| 国产精品每日更新| 久久久久综合| 国产盗摄精品一区二区三区在线| 久久综合狠狠综合| 亚洲三级观看| 蜜臀久久久99精品久久久久久| 日韩免费成人网| 国产一区激情| 亚洲第一综合色| 91精品国产综合久久久久| 欧美精品一卡| 亚洲a一区二区| 欧美一区二区三区色| 欧美日本久久| 肉色丝袜一区二区| 欧美一区二区在线看| 99久久夜色精品国产网站| 国产精品视频九色porn| 亚洲美女色禁图| 极品销魂美女一区二区三区| 国产调教视频一区| 色综合久久99| 99精品视频一区二区| 樱桃视频在线观看一区| 国产成人精品aa毛片| 国产精品久久一级| 91久久精品一区二区| 成人精品视频一区二区三区尤物| 国产精品盗摄一区二区三区| 久久久久综合| 色综合色综合色综合 | 国产亚洲女人久久久久毛片| 亚洲少妇自拍| 国产丶欧美丶日本不卡视频| 亚洲男人天堂av| 8x福利精品第一导航| 国产在线欧美日韩| 蜜桃av一区二区| 中文字幕va一区二区三区| 久久综合九色| 99re这里都是精品| 日日摸夜夜添夜夜添国产精品| 26uuu亚洲综合色| 噜噜噜躁狠狠躁狠狠精品视频| www.99精品| 日韩精品成人一区二区在线| 国产天堂亚洲国产碰碰| 欧美视频一区在线| 在线精品一区二区| 国产精品中文有码| 亚洲欧美另类在线| 日韩视频在线你懂得| 国产精品久久国产愉拍| 99久久综合99久久综合网站| 一区二区成人在线视频 | 免费日韩一区二区| 欧美一区二视频在线免费观看| 日韩精品亚洲一区| 国产精品嫩草久久久久| 欧美精品久久天天躁| 日韩天堂av| zzijzzij亚洲日本少妇熟睡| 无吗不卡中文字幕| 国产欧美一区二区三区在线老狼| 欧美中文字幕一二三区视频| 在线视频观看日韩| 成人美女在线视频| 亚洲成人激情综合网| 国产亚洲欧美一级| 91精品国产乱码久久蜜臀| 久久av一区二区三区| 欧美三级小说| 国产91综合一区在线观看| 亚洲成av人综合在线观看| 国产日韩欧美高清| 欧美日本国产一区| 国产精品综合| 国产一区二区三区四区三区四 | 国产一区 二区 三区一级| 亚洲一二三四区不卡| 久久免费电影网| 欧美高清www午色夜在线视频| 亚洲一卡久久| 国内精品久久久久久久影视麻豆| 国产精品资源网| 毛片av一区二区三区| 亚洲在线视频一区| 国产精品网曝门| 精品国产一区久久| 欧美日本韩国一区| 欧洲国内综合视频| 久久久亚洲人| 国产欧美日韩一区| 在线精品在线| 欧美久久久久久| 国产精品一卡二卡| 另类成人小视频在线| 天天综合色天天| 亚洲国产综合在线| 一个色在线综合| 亚洲免费观看高清完整版在线观看熊| 国产欧美精品一区二区色综合朱莉| 欧美一区二区久久久| 欧美日韩另类国产亚洲欧美一级| 可以免费看不卡的av网站| 国产精品免费在线| 国产精品久久久久久久久久妞妞| 欧美激情一区| 不卡一区在线观看| 国产福利一区二区| 精品一区二区在线看| 日本亚洲一区二区| 午夜不卡av免费| 亚洲电影在线播放| 亚洲制服丝袜在线| 一区二区欧美精品| 亚洲一区二区三区自拍| 亚洲主播在线观看| 亚洲国产毛片aaaaa无费看| 一区二区三区四区亚洲| 亚洲精品中文字幕乱码三区| 亚洲美女屁股眼交3| 综合精品久久久| 成人动漫一区二区| eeuss鲁片一区二区三区| 成人深夜福利app| 成人网在线免费视频| av成人免费在线观看| av一区二区三区四区| 91小视频免费观看| 欧美激情五月| 亚洲国产精选| 国产一区二区三区免费不卡| 久久国产88| 在线视频综合导航| 欧美图区在线视频| 欧美日韩国产乱码电影| 69av一区二区三区| 日韩一级欧美一级| 久久免费偷拍视频| 国产精品伦理在线| 亚洲欧美国产77777|