最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何刪掉編程中的?Switch?語句

 更新時(shí)間:2022年09月06日 11:07:16   作者:Fernando?Doglio  
多重方法是一種有趣的方式,可以幫你擺脫令人討厭的?switch,這篇文章主要介紹了如何刪掉編程中的?Switch?語句,需要的朋友可以參考下

多重方法是一種有趣的方式,可以幫你擺脫令人討厭的 switch。而且,這也有助于提升代碼的可讀性。所以,在決定繼續(xù)堅(jiān)持使用 switch 之前,一定要先試一試。

本文最初發(fā)布于 Bits and Pieces。

很多開發(fā)者都討厭switch語句,包括我。并不是因?yàn)檫@個(gè)語句沒用,也不是因?yàn)樗y了。

理解switch語句的工作原理非常簡(jiǎn)單,問題是當(dāng)你真的遇到它時(shí),就必須停下手頭的一切工作,集中精力閱讀它,以確保不會(huì)遺漏任何東西,比如,缺少break語句可能會(huì)導(dǎo)致一些意想不到的行為,或者一個(gè)case中大約有 20 行代碼。

關(guān)鍵是,原諒我使用一個(gè)花哨的術(shù)語:理解switch語句(在現(xiàn)實(shí)世界中)所需要的認(rèn)知負(fù)荷相當(dāng)重。我相信,作為開發(fā)人員,我們的目標(biāo)是編寫方便人類閱讀的代碼。在這方面,這個(gè)語句提供不了什么幫助。

但是,我寫這篇文章不是為了對(duì)它進(jìn)行抨擊,我是要向你(之前也包括我)展示三個(gè)關(guān)于如何避免使用switch語句的示例,讓我們來看一種函數(shù)式編程技術(shù):多重方法。

什么是多重方法?

我第一次聽到這個(gè)詞,還是在播客“20 MinJS”中采訪 Yehonathan Sharvit 時(shí)。當(dāng)時(shí)的采訪是關(guān)于他即將由 Manning 出版的著作《面向數(shù)據(jù)的編程》。

他提出這一概念是為了從功能上取代繼承,這無疑是可行的。在這個(gè)過程中,他展示了switch語句是如何被取代的。因此,讓我們暫時(shí)把 OOP 放在一邊,只關(guān)注第二部分:消除代碼中丑陋的switch。

什么是多重方法?它只是一個(gè)能夠根據(jù)接收到的參數(shù)選擇最佳實(shí)現(xiàn)的函數(shù)。換句話說,想象一下,如果你把丑陋的switch語句放在函數(shù)中,然后對(duì)所有人隱藏實(shí)現(xiàn)。

唯一的區(qū)別是,你的解決方案只適用于一個(gè)函數(shù)。今天我們將討論如何在運(yùn)行中生成多個(gè)多重方法。

多重方法是什么樣子?

當(dāng)然,每種語言都有自己的變體,但我今天主要講 JavaScript。

在這種語言中,多重方法的使用方法如下:

//我們將使用的數(shù)據(jù)
const myDog = {
    type: "dog",
    name:"Robert"
}
const myCat = {
    type: "cat",
    name: "Steffan"
}
//自定義函數(shù)實(shí)現(xiàn)
function greetDogs (dog) {
    console.log("Hello dear Dog, how are you today", dog.name, "?")
}
function greetCats(cat) {
    console.log("What's up", cat.name, "?")
}
//定義我們的多重方法
let greeter = null
greeter = multi(
    animal => animal.type,
    method("dog", greetDogs),
    method("cat", greetCats)
)(greeter)
// 調(diào)用多重方法
greeter(myDog)
greeter(myCat)

這個(gè)例子做了很多事,讓我來說明下:

  • 我定義了 2 個(gè)對(duì)象myCatmyDog,我將把它們作為參數(shù),多重方法將根據(jù)它們確定自己的行為。

  • 我定義了 2 個(gè)自定義函數(shù)greetDogsgreetCats,它們的實(shí)現(xiàn)稍有不同。它們將代表switch中每個(gè)case語句里的代碼。

  • 然后我調(diào)用一些函數(shù),尤其是multimethod,來定義多重方法greeter。multi函數(shù)接收 3 個(gè)屬性:一個(gè)分配器(dispatcher),我們將用它返回的值來確定要執(zhí)行的邏輯片段;還有兩個(gè)方法,分別代表switch的一個(gè)case語句。請(qǐng)注意,每次調(diào)用method時(shí),要首先指定觸發(fā)第二個(gè)參數(shù)的值(這是實(shí)際的邏輯所在)。

  • 最后,我使用同一個(gè)函數(shù)(我的多重方法)來執(zhí)行兩個(gè)不同的邏輯片段,而不需要在任何地方使用switchif語句。

多重方法有什么好處?

當(dāng)然,我們?cè)谶@里沒有施展任何類型的魔法,我們只是重寫了決策邏輯的表達(dá)方式,類似下面這樣的switch語句:

switch(animal.type) {
  
  case "dog":
    greetDogs(animal);
  break;
  case "cat":
    greetCats(animal);
 break;
}

那么,如果我們可以直接這樣做,為什么還要大費(fèi)周章地使用多重方法呢?問題的關(guān)鍵是可讀性。

switch語句非常開放,顯示了我們的決策邏輯的實(shí)現(xiàn)。換句話說,這個(gè)語句是命令式的。它向你展示了決策樹的內(nèi)部運(yùn)作情況,這意味著閱讀代碼的人將不得不在頭腦中解析代碼。因此,我們又回到了認(rèn)知負(fù)荷的概念。這使得開發(fā)者要閱讀并在頭腦中解析代碼。

你要知道,大多數(shù)開發(fā)人員在遇到像上面這樣的switch時(shí),不會(huì)有什么反應(yīng)。但是,這也不是一個(gè)實(shí)際的例子。通常情況下,case語句包含的代碼更多,也更難閱讀。

而多重方法隱藏了決策邏輯的內(nèi)部結(jié)構(gòu),你所知道的只是你對(duì)它做了設(shè)置,它將以某種方式工作。你更關(guān)心的是功能而不是實(shí)際的實(shí)現(xiàn)。這被稱為“聲明式編程”,有助于提高代碼的可讀性,同時(shí)降低開發(fā)人員的認(rèn)知負(fù)擔(dān)。這是因?yàn)樗谶壿嬌显黾恿艘粚映橄?,為我們提供了更接近人類語言的表達(dá)工具。

如果這還不能說服你,還有一個(gè)優(yōu)點(diǎn):可擴(kuò)展性。

如果你需要在switch中添加另一個(gè)選項(xiàng),就必須回到代碼中修改同一個(gè)switch,如果你,比如說,碰巧忘記添加break語句,就有可能造成問題,就像下面這樣:

switch(animal.type) {
  case "rabbit":
    greetRabbits(animal);
  case "dog":
    greetDogs(animal);
  break;
  case "cat":
    greetCats(animal);
 break;
}

還是個(gè)非常簡(jiǎn)單的例子,但如果是真實(shí)世界中一段更長(zhǎng)的代碼,那么這種情況出現(xiàn)的幾率就更大了。

以防你對(duì)這種行為不熟悉,請(qǐng)讓我做個(gè)說明。第一個(gè)case中缺失break,會(huì)導(dǎo)致在動(dòng)物類型為“rabbit”時(shí)也執(zhí)行第二個(gè)case下的邏輯。

然而,有了多重方法,我們就可以不斷地根據(jù)需要對(duì)它進(jìn)行擴(kuò)展:

let extendedGreeter = multi(
    animal => animal.type,
    method("parrot", sayHiParrot)
)(greeter)

現(xiàn)在,這個(gè)新方法extendedGreeter對(duì)“dog”、“cat“、”parrot“就都有效了,而我們不必再回去修改已有的代碼。

這是一個(gè)很大的好處,因?yàn)槲覀兌贾?,每次我們觸碰可以正常工作的代碼時(shí),都有一點(diǎn)可能引入 Bug。在這里,我們把可能性降低到 0。

實(shí)現(xiàn)一個(gè)多重方法庫(kù)

首先,你要知道,已經(jīng)有一些庫(kù)在處理這個(gè)問題了,其中一個(gè)例子是@arrows/multimethod

盡管如此,對(duì)這些實(shí)現(xiàn)進(jìn)行逆向工程總是很有趣,所以讓我們看一看如何實(shí)現(xiàn)一個(gè)基本的多重方法庫(kù),以適應(yīng)到目前為止所展示的例子。

理解這個(gè)問題的關(guān)鍵是,我們需要一個(gè)分配器函數(shù)來給提供一個(gè)實(shí)際的值,我們將用它作為判斷執(zhí)行哪個(gè)方法的鍵。而且,我們不能對(duì)switch語句進(jìn)行硬編碼,因?yàn)檫x項(xiàng)的數(shù)量是不固定的。

不能光說不練,下面是實(shí)現(xiàn):

function method(value, fn) {
    return {value, fn}
}
function multi(dispatcher, ...methods) {
    return (originalFn) => {
        return (elem) => {
            let key = dispatcher(elem)
            let method = methods.find( m => m.value === key)
            if(!method) {
                if(originalFn) {
                    return originalFn(elem)
                } else {
                    throw new Error("No sure what to do with this option!")
                }
            }
            return method.fn(elem)
        }
    }
}

method函數(shù)只是把鍵和實(shí)際的邏輯耦合在一起,沒有別的。multi函數(shù)中的代碼才有趣,它返回一個(gè)匿名函數(shù),以原始函數(shù)為參數(shù)并返回一個(gè)新函數(shù),后者根據(jù)分配器代碼(我們的第一個(gè)參數(shù))返回的值執(zhí)行不同的東西。

讓我們逐行看下:

  • 首先,調(diào)用第 8 行的函數(shù)時(shí)提供一個(gè)屬性(比方說myDog)。

  • 第 9 行的分配器邏輯會(huì)獲取myDog并返回其類型,即“dog”。

  • 然后在第 10 行,我們找到第一個(gè)與該類型匹配的方法。

  • 如果沒有方法匹配,但我們有一個(gè)有效的“originalFn”(也就是說,我們正在擴(kuò)展一個(gè)原始的多重方法),我們會(huì)讓它來處理這種情況。否則,我們將拋出一個(gè)異常,因?yàn)槲覀儗?duì)此無能為力。

  • 然而,如果找到了匹配的方法,就在第 18 行執(zhí)行它,并將原始屬性“myDog”傳遞給它。

就是這樣。沒那么復(fù)雜,對(duì)嗎?當(dāng)然,如果你想提供“默認(rèn)”情況處理而不是拋出一個(gè)異常,或者你想處理多屬性決策(比如根據(jù)屬性typename決定邏輯,而不是只根據(jù)第一個(gè)屬性),就得編寫更多的代碼了。

不過,還是那句話,如果你打算使用多重方法,建議你使用一個(gè)現(xiàn)有的庫(kù),而不是自己去實(shí)現(xiàn)。

多重方法是一種有趣的方式,可以幫你擺脫令人討厭的switch。而且,這也有助于提升代碼的可讀性。所以,既然你已經(jīng)了解了多重方法,那么在決定繼續(xù)堅(jiān)持使用switch之前,一定要先試一試。

到此這篇關(guān)于如何刪掉編程中的 Switch 語句的文章就介紹到這了,更多相關(guān)Switch 語句刪掉內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入解析Swift語言編程中的可選鏈

    深入解析Swift語言編程中的可選鏈

    這篇文章主要介紹了深入解析Swift語言編程中的可選鏈,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-11-11
  • 解決 Xcode 6-Beta2 智能提示bug

    解決 Xcode 6-Beta2 智能提示bug

    最近開始學(xué)習(xí) Swift ,因?yàn)楦杏X這個(gè)真是個(gè)不錯(cuò)的東西,有很多新的特性,雖然 Titanium 之后也必定會(huì)支持,但總有不少東西要使用原生開發(fā)才可以實(shí)現(xiàn),所以就乘這個(gè)新語言出來之際開始學(xué)習(xí)啦!
    2014-07-07
  • 在Swift中如何使用正則表達(dá)式詳解

    在Swift中如何使用正則表達(dá)式詳解

    正則表達(dá)式是對(duì)字符串操作的一種邏輯公式,相信大家應(yīng)該都不陌生,下面這篇文章主要給大家介紹了關(guān)于在Swift中如何使用正則表達(dá)式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-09-09
  • Swift中風(fēng)味各異的類型擦除實(shí)例詳解

    Swift中風(fēng)味各異的類型擦除實(shí)例詳解

    你也許曾聽過類型擦除,甚至也使用過標(biāo)準(zhǔn)庫(kù)提供的類型擦除類型如 AnySequence,下面這篇文章主要給大家介紹了關(guān)于Swift中風(fēng)味各異的類型擦除的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • 淺談Swift派發(fā)機(jī)制

    淺談Swift派發(fā)機(jī)制

    派發(fā)目的是讓 CPU 知道被調(diào)用的函數(shù)在哪里。Swift 語言是支持編譯型語言的直接派發(fā),函數(shù)表派發(fā)和消息機(jī)制派發(fā)三種派發(fā)方式的,下面分別對(duì)這三種派發(fā)方式說明下。
    2021-06-06
  • swift?cell自定義左滑手勢(shì)處理方法

    swift?cell自定義左滑手勢(shì)處理方法

    這篇文章主要介紹了swift?cell自定義左滑手勢(shì)處理,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Swift條件判斷中逗號(hào)的使用方法示例

    Swift條件判斷中逗號(hào)的使用方法示例

    判斷語句是我們?nèi)粘i_發(fā)經(jīng)常會(huì)遇到的一個(gè)功能,下面這篇文章主要給大家介紹了關(guān)于Swift條件判斷中逗號(hào)的使用方法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • 判斷?ScrollView List?是否正在滾動(dòng)詳解

    判斷?ScrollView List?是否正在滾動(dòng)詳解

    這篇文章主要為大家介紹了判斷?ScrollView、List?是否正在滾動(dòng)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Swift教程之方法詳解

    Swift教程之方法詳解

    這篇文章主要介紹了Swift教程之方法詳解,方法是關(guān)聯(lián)到一個(gè)特定類型的函數(shù),類、結(jié)構(gòu)、枚舉所有可以定義實(shí)例方法,封裝特定任務(wù)和功能處理給定類型的一個(gè)實(shí)例,需要的朋友可以參考下
    2015-01-01
  • Swift下使用UICollectionView 實(shí)現(xiàn)長(zhǎng)按拖拽功能

    Swift下使用UICollectionView 實(shí)現(xiàn)長(zhǎng)按拖拽功能

    拖拽排序是新聞?lì)惖腁pp可以說是必有的交互設(shè)計(jì),如今日頭條,網(wǎng)易新聞等。這篇文章主要介紹了Swift下使用UICollectionView 長(zhǎng)按拖拽功能,需要的朋友可以參考下
    2017-03-03

最新評(píng)論

宁乡县| 桂平市| 开江县| 博罗县| 永靖县| 济源市| 高邑县| 思南县| 海兴县| 开化县| 大邑县| 出国| 遂昌县| 新兴县| 永寿县| 长宁区| 临沧市| 达日县| 科技| 博客| 桦川县| 漳平市| 正蓝旗| 佛坪县| 宁远县| 湾仔区| 新绛县| 乐都县| 咸阳市| 阿坝| 乐至县| 庐江县| 灵台县| 梓潼县| 苍南县| 宽甸| 砚山县| 宁海县| 宝兴县| 霍城县| 龙泉市|