成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[譯] Focal:類型安全、表達力強、可組合的狀態(tài)管理方案

suemi / 741人閱讀

摘要:致力于為應(yīng)用提供一個類型安全表達力強可組合的狀態(tài)管理方案。是一組的命名空間。是內(nèi)置組件的鏡像,但允許組件的額外接受類型的數(shù)據(jù)。這次內(nèi)容更新,是由組件處理的。這些小的組件不必知道所有的應(yīng)用狀態(tài)數(shù)據(jù)。這是因為大部分對的研究來自于。

Focal

Focal 致力于為 React 應(yīng)用提供一個類型安全、表達力強、可組合的狀態(tài)管理方案。

用一個不可變的 (immutable) 、響應(yīng)式的 (observable) 單一數(shù)據(jù)源,來表達整個應(yīng)用的 state.

將響應(yīng)式對象無縫嵌入到 React 的組件中

借助 Rx.JS 的威力,來增強、組合應(yīng)用的 state,來精確控制數(shù)據(jù)流

使用 lenses 將應(yīng)用的 state 分解為若干個較小的部分,幫助你更整潔地解耦 ui 組件,更方便地操作 state

要編寫的代碼更少,更容易理解

Example

我們將通過一個經(jīng)典的計數(shù)器的例子,來展現(xiàn) Focal 在一個完整應(yīng)用中的用法。

import * as React from "react"
import * as ReactDOM from "react-dom"
import {
  Atom,
  // this is the special namespace with React components that accept
  // observable values in their props
  F
} from "@grammarly/focal"

// our counter UI component
const Counter = (props: { count: Atom }) =>
  
    {/* use observable state directly in JSX */}
    You have clicked this button {props.count} time(s).

    
  

// the main "app" UI component
const App = (props: { state: Atom<{ count: number }> }) =>
  
Hello, world! x.count) } />
// create the app state atom const state = Atom.create({ count: 0 }) // track any changes to the app"s state and log them to console state.subscribe(x => { console.log(`New app state: ${JSON.stringify(x)}`) }) // render the app ReactDOM.render( , document.getElementById("app") )
Tutorial

在 Focal 中,state 被存儲在 Atom 中。 Atom 是一個持有一個單一不可變值的數(shù)據(jù)單元。它的寫法是:

import { Atom } from "@grammarly/focal"

// 創(chuàng)建一個初始值為 0 的 Atom
const count = Atom.create(0)

console.log(count.get())
// => 0

// 賦值為 5
count.set(5)

console.log(count.get())
// => 5

// 基于當前值進行重新賦值
count.modify(x => x + 1)

console.log(count.get())
// => 6

你還可以追蹤 Atom 的值的變化(值變化時得到通知)。這意味著,你可以把 Atom 當作響應(yīng)式變量 reactive variable 來看待。

import { Atom } from "@grammarly/focal"

const count = Atom.create(0)

// 訂閱 count 值的變化,每次變化后就往控制臺輸出新值
// NOTE: 注意它將如何立即輸出當前值
count.subscribe(x => {
  console.log(x)
})
// => 0

console.log(count.get())
// => 0

// 賦值后,它會在控制臺自動輸出
count.set(5)
// => 5

count.modify(x => x + 1)
// => 6
Atom 屬性 Atom properties

每個 Atom 都擁有這些屬性:

一旦被訂閱 (.subscribed),立即觸發(fā)響應(yīng),返回當前值( emit the current value)

如果新值和當前值相等,就不觸發(fā)響應(yīng)

單一數(shù)據(jù)源 Single source of truth

在 Focal 中,我們用 Atom 來作為應(yīng)用 state 的數(shù)據(jù)源,F(xiàn)ocal 提供了多種方法來創(chuàng)建 Atom, Atom.create 就是其中一種,我們可以用它來創(chuàng)建應(yīng)用的根 state。
理想情況下,我們期望應(yīng)用的 state 都來自一個單一數(shù)據(jù)源,后面我們會討論如何用這種新方法來管理應(yīng)用的 state 數(shù)據(jù)。

數(shù)據(jù)綁定 Data binding

我們已經(jīng)了解了如何創(chuàng)建、修改和訂閱應(yīng)用的 state 數(shù)據(jù)。下面我們需要了解如何展示這種數(shù)據(jù),從而幫助我們有效地編寫 React UI。

Focal 允許你直接把 Atom 嵌入到 JSX 中。實踐中,這種方式和 Angular 的數(shù)據(jù)綁定有點像。
不過它們還是不太一樣:

在 Focal 里描述數(shù)據(jù)操作時,你編寫的就是標準的 JavaScript 或 TypeScript 代碼,而不必像 Vue 那樣需要借助模板引擎語法。Focal 在語法層面上沒有魔法,所以你原來的語言工具棧都可以繼續(xù)使用。

既然 Focal 的數(shù)據(jù)綁定本質(zhì)還是原生的 TypeScript (or JavaScript) 表達式,你的 IDE 特性就不會失效,比如說自動補全、跳轉(zhuǎn)定義、命名重構(gòu)、用法搜索等。比起模板引擎來說,UI 層代碼維護起來更簡單。

你可以繼續(xù)享受類似于 TypeScript 這樣的靜態(tài)分析工具帶來的好處。因此你的 UI 代碼將和其它代碼一樣可靠。

數(shù)據(jù)(指 Atom)變化,觸發(fā) render。除此以外,別無它法。
通常來說,你不需要考慮組件何時被渲染,一切皆由 Focal 自動處理。

說了這么多,我們看看實際寫起代碼來到底怎么樣:

import * as React from "react"
import * as ReactDOM from "react-dom"
import { F, Atom } from "@grammarly/focal"

// 創(chuàng)建 state
const count = Atom.create(0)

// 定義一個 props 里帶有 Atom 的 stateless 組件
const Counter = (props: { count: Atom }) =>
  
    {/* 直接把 state atom 嵌入到 JSX 里 */}
    Count: {count}
  

ReactDOM.render(
  ,
  document.getElementById("test")
)

// => 
Count: 0

那么問題來了,這跟平常我們寫 React 有什么不同呢?

F-component

在 Focal 里,我們用 來代替一般的

標簽。

React 本來就允許你在 JSX 中嵌入 js 代碼,但是它有諸多限制,會把表達式轉(zhuǎn)為字符串或其它 React elements。

F-component 就不一樣。F 是一組 lifted componenets 的命名空間。lifted component 是 React 內(nèi)置組件的鏡像,但允許組件的 props 額外接受 Atom 類型的數(shù)據(jù)。

我們知道,一個 React JSX 元素中,它的子元素內(nèi)容會被解析為 children prop。Focal 所做的就是支持嵌入 Atom 作為組件的子元素內(nèi)容。

好了,讓我們來試試修改 state 的值:

// 下面這行代碼將修改 atom `count` 的當前值。
// 因為我們在 `Counter` 組件中使用了這個 atom `count`,所以修改了它的值后會使得組件更新
count.set(5)

// => 
Count: 5

你可能已經(jīng)發(fā)現(xiàn)了,我們并沒有修改任何的 React 組件的 state (即沒有通過 Component.setState 的方式),但 Counter 還是不可思議地渲染了新內(nèi)容。
實際上,從 React 的角度來說,Counter 組件的 propsstate 都沒有改變,照道理這個組件也不會被更新渲染。

這次內(nèi)容更新,是由 組件處理的。同理,換成其它 lifted component (或者說 F-component) 也會得到一樣的效果。F-component 會監(jiān)聽 (.subscribe) 它所有的 Atom props,一旦 prop 的值發(fā)生改變,就會 render。

那么根據(jù)這個原理,修改 count 的值以后,子元素 隨之更新渲染,而 則不會。

view

下面我們來編寫稍微復(fù)雜一點的計數(shù)器組件。

// 給我們的計數(shù)器組件加點佐料
const Counter = (props: { count: Atom }) =>
  
    Count: {count}.
    {/* 輸出當前計數(shù)的奇偶性 */}
    That"s an {count.view(x => x % 2 === 0 ? "even" : "odd")} number!
  

// => 
Count: 5. That"s an odd number!

我們加了一行 :That"s an odd/even number!,它是由 state atom 的 view 創(chuàng)建的。

創(chuàng)建一個 view 本質(zhì)上是創(chuàng)建了一個 atom,這個 atom 輸出 state 時,可以表現(xiàn)為它經(jīng)過修改后的值,對其修改的操作邏輯定義在 view 函數(shù)中。
這實際上和 arrayObservablemap 方法差不多,主要的區(qū)別在于,和原生的 atom 一樣,這種衍生 atom (被稱為 view )只會在新值和當前值不相等時才響應(yīng)新值。

我們再看一個例子

const Counter = (props: { count: Atom }) =>
   `rgba(255, 0, 0, ${Math.min(16 * x, 255)})`)
    }}
  >
    Count: {count}.
    That"s an {count.view(x => x % 2 === 0 ? "even" : "odd")} number!
  

// => 
Count: 5. That"s an odd number!

在這里,我們用 state atom 來為組件創(chuàng)建動態(tài)的樣式。如你所見,atom 配合 F-component 幾乎無所不能。它能讓你更簡單地去用聲明式的手段,來描述組件對 state 的依賴。

組合 Composition

我們已經(jīng)了解了如何聲明式地創(chuàng)建基于應(yīng)用狀態(tài)數(shù)據(jù)的 UI 層。接下來,為了使用它們來構(gòu)建規(guī)模更大更復(fù)雜,同時又不致于分崩離析的應(yīng)用,我們還需要兩樣?xùn)|西:

既然應(yīng)用的狀態(tài)數(shù)據(jù)都來自于一個單一數(shù)據(jù)源( 唯一的 atom ),那么當應(yīng)用的不同部分彼此交互時,這些交互行為不會破壞彼此之間的同步性,同時應(yīng)用的狀態(tài)數(shù)據(jù)作為一個整體應(yīng)始終保持一致。

Have the application state come from a single place (a single atom), so that when different parts of the application interact with each other, these interactions can"t fall out of sync with each other and the application state is consistent as a whole.

將應(yīng)用的狀態(tài)數(shù)據(jù)劃分為若干部分,這樣我們可以通過組合若干個小的組件的方式創(chuàng)建我們的應(yīng)用層。這些小的組件不必知道所有的應(yīng)用狀態(tài)數(shù)據(jù)。

這兩個需求可能乍看起來互相矛盾,所以就需要 lenses 登場了。

Lens

讓我們快速復(fù)習(xí)下 lens 的概念
(不知道 lens 的可以參考維基 Haskell/Lens)

一種對不可變數(shù)據(jù)的一部分進行讀寫的抽象

一組 getter 、setter 函數(shù)的組合

lens 的泛型接口可以用 TypeScript 表達為:

interface Lens {
  get(source: TSource): T
  set(newValue: T, source: TSource): TSource
}

來看一個用例

import { Lens } from "@grammarly/focal"

// 后面我們會在 obj 上進行數(shù)據(jù)操作
const obj = {
  a: 5
}

// 用 lens 來查看對象的屬性 `a`
const a = Lens.create(
  // 定義一個 getter:返回 obj 的屬性
  (obj: { a: number }) => obj.a,
  // setter: 返回一個新對象,新對象的屬性 a 被更新為一個新值
  (newValue, obj) => ({ ...obj, a: newValue })
)

// 通過 lens 來訪問屬性
console.log(a.get(obj))
// => 5

// 通過 lens 來寫入一個新值
console.log(a.set(6, obj))
// => { a: 6 }

注意我們是如何通過 .set 方法返回一個新對象的:我們并沒有執(zhí)行修改操作,當我們想要 .set 數(shù)據(jù)的某部分時,我們通過 lens 創(chuàng)建了一個新對象。

這看起來好像沒啥用。為什么我們不直接訪問 obj.a 呢? 當我們需要返回新對象來避免修改操作時,為什么不直接 { ...obj, a: 6 } 呢?

好吧。想象你的對象結(jié)構(gòu)相當復(fù)雜,比如 { a: { b: { c: 5 } } },而它甚至僅僅只是一些更大的對象的一部分:

const bigobj = {
  one: { a: { b: { c: 5 } } },
  two: { a: { b: { c: 6 } } }
}

lenses 的一大特性就是你可以組合 lenses(把它們串聯(lián)起來)。假設(shè)你定義了一個 lens 用來把屬性 c 從對象 { a: { b: { c: 5 } } } 解構(gòu)出來,那么在 bigobjonetwo 這兩個部分上,你都能復(fù)用這個 lens。

// 該 lens 用于操作對象 { a: { b: { c: 5 } } }` 里深度嵌套的屬性 c
const abc: Lens<...> = ...

// 該 lens 用于訪問 `bigobj` 的一部分: `one`
const one: Lens = ...

// 該 lens 用于訪問 `bigobj` 的一部分: `two`
const two: Lens = ...

// 把 lens `one` 或 `two` 和 lens `abc` 組合起來
// 然后我們可以在結(jié)構(gòu)類似為
// `{ one: { a: { b: { c: 5 } } } }` 或 `{ two: { a: { b: { c: 5 } } } }`
// 的數(shù)據(jù)中操作 c
const oneC = one.compose(abc)
const twoC = two.compose(abc)

console.log(oneC.get(bigobj))
// => 5

console.log(twoC.get(bigobj))
// => 6

console.log(oneC.set(7, bigobj))
// => { one: { a: { b: { c: 7 } } }, two: { a: { b: { c: 6 } } } }

Focal 也提供了相當方便的定義這些 lenses 的手段。

// 只需要定義一個 getter 函數(shù)就可以創(chuàng)建上述的 lenses1
const abc = Lens.prop((obj: typeof bigobj.one) => obj.a.b.c)

const one = Lens.prop((obj: typeof bigobj) => obj.one)

const two = Lens.prop((obj: typeof bigobj) => obj.two)

// 1 注意使用限制?。≧ESTRICTIONS APPLY!)
// 在這個例子里,getter 函數(shù)只能是一個簡單的屬性路徑訪問函數(shù)
// 該函數(shù)僅包括一個屬性訪問表達式,沒有副作用 (side effects)

其中最棒的一點是,這種方式是完全類型安全的,所有的 IDE 工具(比如說自動補全、命名重構(gòu)等)都仍然有效。

可能比較奇怪的一點是,lens 照道理應(yīng)該還可以修改該值,但我們只定義了一個 getter 函數(shù)。這確實不可思議,因為我們在這里施了點魔法。但是,這只能被視為一個實現(xiàn)細節(jié),因為這些特性在將來可能在 TypeScript 編譯器中就過時了。

簡單解釋下,我們用的方案可能類似于 WPF 里用來實現(xiàn)類型安全的 INotifyPropertyChanged 接口的標準實踐。我們通過調(diào)用 .toString 函數(shù),把 getter 函數(shù)轉(zhuǎn)換成一個字符串,然后根據(jù)函數(shù)的源碼解析出屬性的訪問路徑。這種實現(xiàn)方式比較 hacky ,還有著明顯的限制,不過還是很有效的。

關(guān)于 lenses 的更多資料

希望上一章能讓你稍微領(lǐng)略一下 lenses 的威力,當然你還可以用這個抽象來做更多的事情。遺憾的是我們沒法在這個簡短的教程里覆蓋 lens 所有有趣的部分。

不幸的是,大部分關(guān)于 lenses 的文章和介紹都是用 Haskell 來描述的。這是因為大部分對 lenses 的研究來自于 Haskell。不過很多其它語言也采用了 lenses ,包括 Scala, F#, OCaml, PureScript 和 Elm 等。

Program imperatively using Haskell lenses

WikiBooks article on Haskell lenses

School of Haskell lens tutorial

lens over tea blog series

Atoms 和 lenses

好,言歸正傳。到此為止,我們已經(jīng)知道了如何管理應(yīng)用狀態(tài)數(shù)據(jù),如何把狀態(tài)數(shù)據(jù)嵌入到我們的 UI 層代碼中。

我們還學(xué)習(xí)了如何抽象對不可變數(shù)據(jù)的操作,以便方便地對大型的不可變對象的部分進行操作。我們正是需要用它來拆分應(yīng)用的狀態(tài)數(shù)據(jù)。我們想要這樣構(gòu)造我們的應(yīng)用:UI 組件的各部分僅和整個應(yīng)用狀態(tài)數(shù)據(jù)中和它有關(guān)的那部分交互。

為了實現(xiàn)這個目的,我們可以通過結(jié)合 atom 和 lens 來生成 lensed atom。

Lensed atom 也還是一個 Atom,或者說從表面來看,它的表現(xiàn)和行為也和別的 atom 幾乎一樣。區(qū)別在于它的創(chuàng)建方式:lensed atom 操作于其它 atom 的一部分 state。這意味著,如果你通過 .set.modify 來設(shè)置或修改一個 lensed atom 的值,那么源 atom 上與該 lensed atom 對應(yīng)的這部分的值也會隨之改變。比如:

import { Atom, Lens } from "@grammarly/focal"

// 創(chuàng)建一個維護我們所需對象(的值)的 atom
const obj = Atom.create({
  a: 5
})

// 創(chuàng)建一個觀察屬性 a 的 lens
const a = Lens.prop((x: typeof obj) => x.a)

// 創(chuàng)建一個 lensed atom,這個 lensed atom 會維護對象 obj 的屬性 a 的值
const lensed = obj.lens(a)

console.log(obj.get())
// => { a: 5 }

console.log(lensed.get())
// => 5

// 為 lensed atom 設(shè)置新值
lensed.set(6)

console.log(obj.get())
// => { a: 6 }

注意,當我們?yōu)?lensed atom 設(shè)置新值的時候,源 atom 的值是如何變化的。

我們還有一種更簡潔的方法來創(chuàng)建 lensed atom:

const lensed = obj.lens(x => x.a) // 1

// 1 還是要注意使用限制 SAME RESTRICTIONS APPLY!
// 和 `Lens.prop` 方法一樣,atom 的 `lens` 方法接受一個 getter 函數(shù)作為參數(shù),
// 這個 getter 函數(shù)只能是一個簡單的屬性路徑訪問函數(shù),
// 它僅包括一個屬性訪問表達式,沒有副作用。

我們無需顯式地去創(chuàng)建 lens,atom 的 lens 方法已經(jīng)提供了幾個重載來幫助你立即創(chuàng)建 lensed atom。另外需要注意的是,我們不需要在此為對象添加類型標注,編譯器已經(jīng)知道了我們正在操作的數(shù)據(jù)的類型,并且為我們自動推斷出來(比如在上面那個例子里,根據(jù) obj 的類型 Atom<{ a: number }>,編譯器可以自動推斷出 x 的類型)

基于這種能力,現(xiàn)在我們可以拆分應(yīng)用的單一數(shù)據(jù)源為幾個小的部分,使其適用于獨立的 UI 組件中。讓我們來嘗試把這一方案用在上述的計數(shù)器例子中:

import * as React from "react"
import * as ReactDOM from "react-dom"
import { Atom, F } from "@grammarly/focal"

// 應(yīng)用的狀態(tài)數(shù)據(jù)
const state = Atom.create({
  count: 0
})

// 原先寫好的計數(shù)器組件
const Counter = (props: { count: Atom }) =>
  
    Count: {props.count}.

    
  

// app 組件,其 prop.state 攜帶整個應(yīng)用的狀態(tài)數(shù)據(jù)
const App = (props: { state: Atom<{ count: number }> }) =>
  
Hi, here"s a counter: {/* 在此,我們拆分應(yīng)用狀態(tài)數(shù)據(jù),把其中的一部分給 counter 組件使用 */} x.count)} />

我們就用這個例子作為 Focal 基礎(chǔ)教程的總結(jié)吧。

希望你現(xiàn)在能理順上面這些東西是如何結(jié)合起來的。另外,還請務(wù)必看看一些其它例子
。嘗試搭建并嘗試跑通它們,方便進一步了解你可以用 focal 來做什么。

這是一個框架嗎?

Focal 不是一個框架,換句話說,它并不限制你非要用要某種特定的方式來編寫整個應(yīng)用。Focal 提供了命令式的接口 (回想下,你可以用 .set.modify 方法來操作 atom ),并且可以完美地配合原生的 React 組件。這意味著,在同一個應(yīng)用里,你可以只在某些部分使用 Focal。

性能

盡管我們還沒有建立一套全面的評測基準 (benchmarks),目前為止,在類似 TodoMVC 的例子中,F(xiàn)ocal 的性能表現(xiàn)至少近似于原生 React。

一般來說,當一個被嵌入到 React 組件里的 AtomObservable 觸發(fā)一個新值時,組件中只有相關(guān)的那部分會被更新。

這意味著,在一個復(fù)雜的 React 組件中,如果你在該樹某處相當深的可見部位,有一個頻繁變更的值,那么當該值變化時,只有對應(yīng)的那部分會更新,而不是整個組件樹都會更新。在很多場景下,這使得我們很容易為 VDOM 的重計算做優(yōu)化。

商業(yè)應(yīng)用

JavaScript 支持

盡管從技術(shù)上來說可以把 Focal 用于純 Javascript 項目,但是我們還沒嘗試過這樣做。所以,如果你在搭建這種項目時遇到了問題,歡迎前來提交 issues。

Prior art

Focal 起初只是想把 Calmm 轉(zhuǎn)接到 TypeScript ,但隨后我們因為一些顯著的差異而放棄了。

一開始,我們更專注于快速開發(fā)產(chǎn)品和類型安全。基于此,許多東西都被簡化了,所以在當時(TypeScript 版本為 1.8 時)Focal 還很難和類型系統(tǒng)搭配得很好,API 也不夠直觀,也很難讓新入門函數(shù)式編程的 React 老用戶快速上手。

和 Calmm 的區(qū)別

Calmm 是模塊化的,由幾個獨立的庫組成。而 Focal 沒必要模塊化,因為我們只有一種使用場景,所以我們只需要在一個庫里維護所有東西。

Calmm 最初大量借助 Ramda 的 curry 和 Partial Application。這不利于搭配類型系統(tǒng),所以我們決定放棄這種做法。不過隨著 TypeScript 編譯器的進步,現(xiàn)在要去實現(xiàn)上面那種做法可能變得容易多了,所以這也許會是一個有趣的話題。

Calmm 最初還借用了 Ramda 里的 lens ,這種 lens 使用的是 van Laarhoven 表示法。相反,F(xiàn)ocal 使用的是含有一對 getter/setter 的 na?ve 表示法。由于我們無需去做遍歷或多態(tài)更新 (traversals or polymorphic updates),所以這對我們來說足夠了。不過有可能我們會在以后重新考慮這個問題。

Calmm 的主要實現(xiàn) (kefir.atom 和 kefir.react.html) 都基于 Kefir 的 observables。一開始我們也用 Kefir,不過很快遷移為 RxJS 5.x。最主要的原因是,RxJS 功能更豐富,它有一些 Kefir 還不支持的對 observables 的操作。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84957.html

相關(guān)文章

  • React組件設(shè)計實踐總結(jié)05 - 狀態(tài)管理

    摘要:要求通過要求數(shù)據(jù)變更函數(shù)使用裝飾或放在函數(shù)中,目的就是讓狀態(tài)的變更根據(jù)可預(yù)測性單向數(shù)據(jù)流。同一份數(shù)據(jù)需要響應(yīng)到多個視圖,且被多個視圖進行變更需要維護全局狀態(tài),并在他們變動時響應(yīng)到視圖數(shù)據(jù)流變得復(fù)雜,組件本身已經(jīng)無法駕馭。今天是 520,這是本系列最后一篇文章,主要涵蓋 React 狀態(tài)管理的相關(guān)方案。 前幾篇文章在掘金首發(fā)基本石沉大海, 沒什么閱讀量. 可能是文章篇幅太長了?掘金值太低了? ...

    ideaa 評論0 收藏0
  • 】每個JavaScript 開發(fā)者應(yīng)該了解10個面試題

    摘要:避免脆弱的基類問題。紅牌警告沒有提到上述任何問題。單向數(shù)據(jù)流意味著模型是單一的事實來源。單向數(shù)據(jù)流是確定性的,而雙向綁定可能導(dǎo)致更難以遵循和理解的副作用。原文地址 1. 你能說出兩種對 JavaScript 應(yīng)用開發(fā)者而言的編程范式嗎? 希望聽到: 2. 什么是函數(shù)編程? 希望聽到: 3. 類繼承和原型繼承的不同? 希望聽到 4. 函數(shù)式編程和面向?qū)ο缶幊痰膬?yōu)缺點? ...

    mykurisu 評論0 收藏0
  • PHP / Laravel API 開發(fā)推薦閱讀清單

    showImg(https://segmentfault.com/img/bV6aHV?w=1280&h=800); 社區(qū)優(yōu)秀文章 Laravel 5.5+passport 放棄 dingo 開發(fā) API 實戰(zhàn),讓 API 開發(fā)更省心 - 自造車輪。 API 文檔神器 Swagger 介紹及在 PHP 項目中使用 - API 文檔撰寫方案 推薦 Laravel API 項目必須使用的 8 個...

    shmily 評論0 收藏0
  • 打造Win10下完美Linux體驗(WSL2+WindowsTerminal+oh-my-zsh),

    摘要:以管理員身份打開分別輸入輸入完成后重啟電腦,以完成安裝并更新到。將設(shè)置為默認版本在微軟商店內(nèi)下載分發(fā)版,這里我下載的是。且被視為管理員,能夠運行管理命令。 目錄 ...

    孫淑建 評論0 收藏0
  • []Mixin 函數(shù)

    摘要:函數(shù)通常是面向?qū)ο缶幊田L(fēng)格,具有副作用。因為在函數(shù)式編程中,很有可能這些引用指向的并不是同一個對象。記住,函數(shù)并不意味著函數(shù)式編程。函數(shù)可以用函數(shù)式編程風(fēng)格編寫,避免副作用并不修改參數(shù),但這并不保證。 軟件構(gòu)建系列 原文鏈接:Functional Mixins 譯者注:在編程中,mixin 類似于一個固有名詞,可以理解為混合或混入,通常不進行直譯,本文也是同樣。 這是軟件構(gòu)建系列教...

    zxhaaa 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<