成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

TypeScript 之痛,為啥很多人會用成 AnyScript

開發(fā) 前端
TypeScript 作為類型約束的語言,在套在強(qiáng)調(diào)類型靈活性的 JavaScript 上時,在實(shí)際的使用過程中是有非常多的鎮(zhèn)痛的,甚至有很多即使用了類型體操都無法解決的問題,因?yàn)樗麄儚牡讓颖举|(zhì)上來說,確實(shí)有許多無法統(tǒng)一的邏輯和場景。

簡單給大家說一下案例背景。

我在寫我的付費(fèi)專欄「圖解算法」時,準(zhǔn)備基于拉鏈法實(shí)現(xiàn)一個 HashMap 對象,并且準(zhǔn)備用環(huán)形鏈表來存儲碰撞到一起的輸入值。

完整的存儲結(jié)果,大家可以通過上圖來理解。

?

由于環(huán)形鏈表的算法結(jié)構(gòu),在 React 底層原理中被大量運(yùn)用,因此,是大廠面試的高頻考題之一。而哈希碰撞 + 環(huán)形鏈表則是一個綜合性較強(qiáng)的場景,是一個考察高級開發(fā)候選人的基礎(chǔ)是否扎實(shí)的比較合適的題目,各位面試官也可以借鑒

然而,在實(shí)現(xiàn)這個代碼的過程中,我卻在一個 TypeScript 的類型問題上遇到了麻煩。

按照既有的思路,我首先需要定義一個鏈表節(jié)點(diǎn)的類型,該節(jié)點(diǎn)存儲 key-value 鍵值對。這里由于 Map 支持的 key 值是任意類型,value 的類型也不確定,因此,我的本能反應(yīng),就是使用 any 來約定類型,然后再加一個指向下一個節(jié)點(diǎn)的指針 next

type HNode = {
  key: any,
  value: any,
  next: HNode | null
}

但是很明顯啊,直接用 any 肯定是不那么專業(yè)的,因此呢,我就不得不花額外的精力去思考到底應(yīng)該用什么樣的類型比較合適。

由于 key-value 都是從外部傳入的,因此比較標(biāo)準(zhǔn)一點(diǎn)的做法,是可以傳入泛型變量來站位

可以改造成這樣

type HNode<K, V> = {
  key: K,
  value: V,
  next: HNode<K, V> | null
}

但是,改造成這樣之后呢,麻煩的事情就來了。他與 Map 的語法定義就不匹配了。為啥我要這么說呢?

我們都知道,在使用 Map 的時候,如果我們傳入兩個 key-value 的值進(jìn)來,這兩個鍵值對的 key 類型與 value 類型,在語法上,是沒有強(qiáng)制要求他們必須是相同的。

例如,在同一個 Map 中,我們可以分別存儲如下兩個鍵值對

const m = new Map<any, any>()
m.set('tom', {})
m.set(1024, 'hello world!')

但是,我們一旦用泛型來約束之后,這樣寫就難受了呀,最終還是只能傳入 any 才能解決問題。

當(dāng)然,這是一方面,另外一方面,你會發(fā)現(xiàn),一個簡單的場景,為了解決類型問題,你又多花了大量的時間。要完美解決的話,又得引入重載,這運(yùn)用成本就嘎嘎嘎的往上升。

最后發(fā)現(xiàn),還是 any 省事兒!

后面還有一個場景,如下代碼所示,我在編寫 set 方法,先簡單瞄一眼代碼,后面再分析。

// 插入鍵值對
set(key: K, value: V) {
  const index = this.hash(key);
  const bucket = this.buckets[index]

  const node: HNode<K, V> = {
    key: key,
    value: value,
    next: null
  }

  // 如果桶是空的,初始化一個鏈表
  if (!bucket) {
    node.next = node
    this.buckets[index] = {
      length: 1,
      last: node
    };
    return
  }

  const last = bucket.last
  const first = last?.next

  // 檢查是否已存在相同的key
  let current: HNode<K, V> = bucket.last
  while(true) {
    if (current.key === key) {
      current.value = value
    }
    current = current.next
    if (current === bucket.last) {
      break
    }
  }

  // add the node to last
  last.next = node
  node.next = first
  bucket.last = node
  bucket.length += 1
}

set 的語法如下

const m = new HashMap()
m.set(1001, {})

在底層實(shí)現(xiàn)中,由于我們需要將鍵值對插入到鏈表中,因此在插入之前,就需要先定義好節(jié)點(diǎn)。這里的一個問題就是,我這個節(jié)點(diǎn)的指針類型的值,應(yīng)該是什么?

默認(rèn)理所應(yīng)當(dāng)應(yīng)該是 null,因此此時還不知道會指向誰呢?

const node: HNode<K, V> = {
  key: key,
  value: value,
  next: null
}

但是,真實(shí)的場景是,由于我們使用的是環(huán)形鏈表,因此這里的 next 實(shí)際上是總有值的,最差也是指向自身。只要有節(jié)點(diǎn)存在,他就不可能為 null

node.next = node

因此,如何要和實(shí)際情況匹配的話,我們就不應(yīng)該將其設(shè)置為 null。

但是由于在初始化時,語法不允許直接指向自身,所以這里就不得不先將其設(shè)置為 null,在根據(jù)條件判斷來確定指向

但是,這就會引發(fā)后續(xù)的麻煩,后續(xù)當(dāng)我要獲取一個節(jié)點(diǎn)時,由于真實(shí)情況是,我一定能獲取到一個節(jié)點(diǎn),不會存在獲取到為 null 的情況,但是由于我們在類型的定義上,將其設(shè)置為了 null,這個時候,就不得不額外處理獲取值為 null 的情況

這特么代碼寫起來就賊難受。

我就只能用 as 來強(qiáng)制約定類型

current = current.next as HNode<K, V>

或者干脆就直接在定義的時候,全給寫成 any,就啥麻煩事兒都沒有了

type HNode = {
  key: any,
  value: any,
  next: any
}

總結(jié)

TypeScript 作為類型約束的語言,在套在強(qiáng)調(diào)類型靈活性的 JavaScript 上時,在實(shí)際的使用過程中是有非常多的鎮(zhèn)痛的,甚至有很多即使用了類型體操都無法解決的問題,因?yàn)樗麄儚牡讓颖举|(zhì)上來說,確實(shí)有許多無法統(tǒng)一的邏輯和場景。

這是許多人把 ts 用成 anyScript 的原因。

當(dāng)然,適當(dāng)使用 any,絕對不是技術(shù)水平不行的表現(xiàn)。我們要學(xué)會在使用成本和類型約束之間,做一個合適的取舍。一方面我們要適當(dāng)約束 JS 的靈活性以迎合 TS 的規(guī)則,另外一方面,我們也要適當(dāng)使用 any 釋放 TS 的靈活性,來降低開發(fā)成本。否則,我們的開發(fā)體感就會變得很差,會被 TypeScript 搞的很難受。

責(zé)任編輯:姜華 來源: 這波能反殺
相關(guān)推薦

2019-12-09 10:02:41

泛型ypeScript前端

2025-02-21 08:48:16

Typescript內(nèi)置聯(lián)合類型

2021-01-30 11:42:53

迭代器代碼元素

2024-09-12 08:32:42

2018-02-13 14:48:17

戴爾

2022-02-06 00:07:19

互聯(lián)網(wǎng)失業(yè)職業(yè)

2021-10-08 15:50:14

手機(jī)屏幕安卓

2019-08-21 08:24:34

技術(shù)過濾器代碼

2021-06-24 09:08:34

Java代碼泛型

2022-07-06 10:33:39

技術(shù)債務(wù)CIO

2017-12-13 15:57:12

2021-01-15 05:39:13

HashMapHashTableTreeMap

2020-06-29 08:28:36

v-for 解構(gòu)函數(shù)

2014-05-09 15:29:21

2020-11-16 11:24:00

Spring AOP數(shù)據(jù)庫

2021-09-21 10:33:56

人工智能科學(xué)技術(shù)

2022-01-05 23:34:02

顯示器濾藍(lán)光LED

2019-08-08 16:00:08

HTTPGETPOST

2021-02-22 13:14:00

計(jì)算機(jī)編程技術(shù)

2020-06-08 19:16:52

大數(shù)據(jù)IT技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美在线视频网站 | 99福利视频 | 欧美成人久久 | 日韩在线欧美 | 亚洲天堂一区 | 中文字幕不卡在线观看 | 久久久国产一区 | 欧美一级在线免费 | 免费黄色日本 | 国产亚洲精品综合一区 | 九九精品在线 | 国产乱码一区 | av在线二区 | 国产精品福利在线观看 | 伊人春色在线观看 | 国产精品久久久久久久久久久久 | 精品欧美激情精品一区 | 日日碰碰 | 亚洲444kkkk在线观看最新 | 中文在线一区 | 国产成人精品久久久 | 国产一级在线视频 | 欧美激情亚洲 | 久草.com | 欧美成人免费在线 | 久久久久亚洲精品 | 国产精品久久久久久久久久久久 | 不卡一区二区三区四区 | 特级丰满少妇一级aaaa爱毛片 | 在线中文字幕国产 | 337p日本欧洲亚洲大胆 | 午夜在线| 国产午夜精品一区二区三区嫩草 | 国内久久| 日韩视频―中文字幕 | 日韩精品一区二区三区高清免费 | 国产高清免费 | 综合欧美亚洲 | 国产片一区二区三区 | 日韩欧美网 | 欧美aⅴ|