CC
云谦的博客
发布于 2025年12月23日

译:“无”也是一种“有”

原文: https://kyleshevlin.com/nothing-is-something/
作者: Kyle Shevlin
译者: Gemini 3 Pro High

我真的需要更多人去观看 Sandi Metz 的 “Nothing is Something”(无也是一种有),这样当我在代码中应用其中的教训时,就不会收到奇怪的目光了。

今天我正在处理类似下面这样一个问题。想象你有一个键值对对象,其中键代表某种状态,而值则是对该状态的某种转换。

// Just some arbitrary state for our example
type State = {
  count: number
  createdAt: Date
  isActive: boolean
  name: string
}

type Transform = <T>(x: T) => T

const STATE_TRANSFORMS: Partial<Record<keyof State, Transform>> = {
  count: x => x * 2,
  name: x => x.toUpperCase(),
}

这些转换本身并不特别重要,但请注意,我并没有为 State 类型中的每一个键都提供转换。

现在,如果你要编写一个函数来运行这些转换,你可能会想这样做:

function transformStates(state: State) {
  const nextState: State = {}

  for (const key of state) {
    const transform = STATE_TRANSFORMS[key]

    // This handles the condition at the last possible moment
    // and it results in two separate ways of managing the state
    if (transform) {
      nextState[key] = transform(state[key])
    } else {
      nextState[key] = state[key]
    }
  }

  return nextState
}

但我更喜欢这样做:

const identity = x => x

function transformStates(state) {
  const nextState = {}

  for (const key of state) {
    // Condition is handled a step earlier and we've narrowed
    // the type of `transform` from `Transform | undefined`
    // to just `Transform`, simplifying the next step
    const transform = STATE_TRANSFORMS[key] ?? identity

    nextState[key] = transform(state[key])
  }

  return nextState
}

因为,正如演讲标题所暗示的,什么都不做(doing nothing)本身就是在做某事(doing something)。

你可能会争辩说我在这里进行了不必要的函数调用,但我认为为了代码的简洁,这是一个值得的权衡。

我们可以利用这种模式——即识别“无”(也就是默认行为)并为其提供功能——作为简化代码的一种方式,主要是通过减少过多的条件判断,而条件判断往往是复杂性的来源。

请观看那个演讲。你会因此成为一名更好的程序员。

评论 (0)

请登录后发表评论

暂无评论,快来发表第一条评论吧!