日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

JS語法也可以有C#的switch表達式

瀏覽:54日期:2022-06-09 15:19:28
目錄
  • 正文
  • 新的約束
  • when 函數寫法
  • 分算等級”測試
    • 測試問題
    • 升級成 TypeScript

正文

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

C# 8.0 引入了 switch 表達式。C# 的 switch 表達式有著非常豐富的語法元素,可以和模式匹配和解構等語法元素協同工作 —— 這些都不在這里細說,但是對傳統的 switch 語句 進行了一些改進:

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

新的約束

  • switch 表達式一定要詳盡(邏輯一定會走進某一個 case,可以通過棄元模式兜底),否則可能會在運行時引發異常。

在 C# 8.0 發布的同年,Java 12 也發布并引入了 switch 表達式預覽。Java 的 switch 表達式實現比較簡單,就是 switch 語句到 switch 表達式的直接轉換,僅支持等值匹配。直到 2023 年 3 月 Java 20 發布,switch 表達式才開始支持模式匹配。相比之下,Kotlin 的 when 表達式走在了前面。

在這個問題上 JavaScript 似乎走在了后面,不過在語言提供 switch 表達式之前,我們可以嘗試自己造個輪子。

思路當然是參考策略模式。假設有一個列表,這個列表里的每個元素都包含了兩個因素:第一個用于判斷是否命中,第二個是個函數,得到一個計算結果。然后寫一個循環遍歷列表的每個元素,一旦某個元素命中,就執行元素攜帶的函數獲得結果,中斷循環,返回結果。如果列表的最后一個元素必定命中,那么這個列表就是“詳盡”的。

when 函數寫法

那么這個 when 函數可能會這樣寫(switch 是關鍵字,所以使用 when 來作為函數名):

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

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

分算等級”測試

相應地,我們可以經典的“拿分算等級”來進行測試:

// 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 => `無效 (${v})` },
    );
}
for (let i = 0; i < 50; i++) {
    const v = 70 + ~~(Math.random() * 35);
    console.log(calcGrade(v));
}

在 calcGrade 實現中 when 的 case 列表最后一項采用了“永真”斷言,所以走到這一項的時候一定會命中,從邏輯上來永遠不會觸發 Error。如果是非“詳盡”的情況列表,就有可能觸發 Error。

測試問題

不過現在從測試代碼中就發現了兩個問題:

  • is 斷言是采用函數的形式,不能簡單地直接按值匹配;
  • 從調用形式上來說,score 和后面的 case 元素是同級的,形式上區分不明顯;
  • 每次都要寫 is 和 run,條件多了寫起來也煩。

繼續改進 ——

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

為什么兜底斷言必須使用一個函數呢?因為 true 值也有可能是對應一種預想的分支情況。由于這個 when 是通過語義來實現而不是通過語法來實現的,所以這里沒辦法定義一個安全的兜底斷言語法,只有用斷言函數會相對安全。

升級成 TypeScript

至此為止我們已經基本實現了 switch 表達式 (when),把它升級成 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 => `無效 (${v})`],
    );
}

這段代碼當然可以直接用,但是如果使用 npm 可能會更方便一點:

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 => `無效 (${v})`],
    );
}

以上就是JS語法也可以有C# 的switch表達式的詳細內容,更多關于JS語法C# switch表達式的資料請關注其它相關文章!

標簽: JavaScript
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美亚洲tv| 精品免费av在线| 1024精品一区二区三区| 精品国产美女a久久9999| 国产精品久久久久久久久免费高清| 日本电影久久久| 青青青国产精品| 国产视频一区二| 国产欧美精品久久| 欧美黑人做爰爽爽爽| 麻豆91在线播放| 日韩av二区| 精品一区二区三区免费看| 麻豆精品久久久| 国产一区国产二区国产三区| 久久免费精品| 伊人网在线播放| 久久精品免费一区二区三区| 亚洲女同中文字幕| 综合国产在线| 欧美日韩中文| 福利一区二区免费视频| 免费一二一二在线视频| 欧美日韩水蜜桃| 老司机久久99久久精品播放免费| 蜜桃视频免费观看一区| 日韩av一区二区三区| 国产精东传媒成人av电影| 欧美成a人片免费观看久久五月天| 精品国产乱码久久久| 群体交乱之放荡娇妻一区二区| 亚洲精品午夜av福利久久蜜桃| 中文不卡在线| 国产日韩视频| 色婷婷综合网| 九色精品91| 麻豆一区二区三区| 免费av一区二区三区四区| 久热精品在线| 精品中国亚洲| 黑丝美女一区二区| 亚洲精一区二区三区| 国产另类在线| 国产乱码午夜在线视频| 久久福利精品| 国产精品啊v在线| 美女网站视频一区| 石原莉奈在线亚洲二区| 国产免费播放一区二区| 日韩在线精品| 亚洲精品福利| 免费看av不卡| 中文字幕一区二区三区四区久久| 国产精品成人一区二区网站软件| 久久久久国产| 91精品国产自产精品男人的天堂| 岛国av免费在线观看| 免费高清在线一区| 国产精久久久| 亚洲欧美日韩精品一区二区| 国产精品免费精品自在线观看| 久久精品中文| 国产精品美女在线观看直播| 99视频在线精品国自产拍免费观看| 欧美午夜三级| 精品中文字幕一区二区三区av| 日韩av中文字幕一区| 欧洲一级精品| 欧美日本三区| 狠狠爱成人网| 久久久久久亚洲精品美女| 亚洲激情av| 国产精品国产三级国产在线观看| 亚洲免费成人| 国产理论在线| 国产色噜噜噜91在线精品| 欧美高清一区| 成人免费一区| 日韩国产在线观看一区| 欧美日韩国产免费观看| 精品视频一区二区三区四区五区| 香蕉久久国产| 天堂av在线| 国产精久久久| 日韩av网站在线免费观看| 国产精品88久久久久久| 精品三级在线| 日本视频中文字幕一区二区三区| 久久青草久久| 久久97久久97精品免视看秋霞| 亚洲欧美在线综合| 欧美日韩国产精品一区二区亚洲| 国产美女高潮在线| 国产精品久久久亚洲一区| 亚洲最新av| 婷婷综合网站| 日韩电影免费网站| 美女视频免费精品| 日韩av网站在线免费观看| 美女被久久久| 国产综合视频| 久久久国产亚洲精品| 精品国产网站| 91精品麻豆| 亚洲久草在线| 鲁大师影院一区二区三区| 欧美日韩亚洲在线观看| 亚洲永久av| 精品香蕉视频| 你懂的国产精品| 国产日产一区| 久久精品av麻豆的观看方式| 蜜臀精品一区二区三区在线观看 | 美女精品在线观看| 日韩欧美一区二区三区免费看| 国产精品天天看天天狠| 日本在线视频一区二区| 亚洲乱码视频| 亚洲精品美女91| 三级在线观看一区二区| 视频一区二区三区在线| 欧美综合二区| 日韩专区欧美专区| 日韩专区欧美专区| 久久国产高清| 免播放器亚洲一区| 亚洲人成亚洲精品| 日韩精品一区二区三区中文| 91伊人久久| 欧美亚洲自偷自偷| 国产麻豆一区二区三区精品视频| 日韩av不卡一区二区| 91精品美女| 欧美国产精品| 国产一区二区三区探花| 国产第一亚洲| 亚洲www免费| 久久国产小视频| 99国产精品久久久久久久| 久久亚洲欧美| 青草国产精品久久久久久| 国产欧美88| 日韩av有码| 99久久www免费| 91精品福利| 影音先锋久久精品| 欧美精品三级在线| 日产精品一区二区| 久久中文字幕二区| 麻豆精品91| 欧美一级一区| 日韩不卡一区| 日韩视频不卡| 日本免费在线视频不卡一不卡二| 国产精品白丝久久av网站| 亚洲天堂资源| 免费久久99精品国产自在现线| 亚洲18在线| 久久精品亚洲一区二区| 亚洲www啪成人一区二区| 性欧美69xoxoxoxo| 日本一区二区三区视频在线看| 国产精品久久久久久久久久齐齐 | 日韩国产欧美在线播放| 国产精品久久久久9999高清| 高清日韩中文字幕| 好看不卡的中文字幕| 日本中文字幕视频一区| 精品无人区麻豆乱码久久久| 精品一区在线| 日韩精品亚洲专区| 久久婷婷国产| 欧美91视频| 日韩精品91亚洲二区在线观看| 视频一区日韩| 免费在线成人| 精品一区在线| 欧美日韩中出| 日韩黄色大片| 亚洲精品伊人| 97视频热人人精品免费| 国产午夜精品一区二区三区欧美| 欧美天堂一区二区| 久久国产中文字幕| 日本欧美一区二区在线观看| 久久久夜夜夜| 亚洲a成人v| 偷拍精品精品一区二区三区| 亚洲欧美日本国产| 91看片一区| 国产日韩欧美一区| 亚洲高清不卡| 国产亚洲久久| 国产伦理一区| 亚洲免费激情| 国内一区二区三区| 蜜臀精品一区二区三区在线观看 | 视频一区国产视频| 精品一区二区三区亚洲 | 激情婷婷综合|