Go 重构:尽量避免使用 else、break 和 continue

else 操作
例如,我们有简单的用户处理程序:

func handleRequest(user *User) {
   
    if user != nil {
   
        showUserProfilePage(user)
    } else {
   
        showLoginPage()
    }
}

如果没有提供用户,则需要将收到的请求重定向到登录页面。If else 似乎是个不错的决定。但我们的主要任务是确保业务逻辑单元在任何输入情况下都能正常工作。因此,让我们使用提前返回来实现这一点。

func handleRequest(user *User) {
   
    if user == nil {
   
        return showLoginPage()
    } 
    showUserProfilePage(user)
}

逻辑是一样的,但是下面的做法可读性会更强。
break 操作
对我来说,Break 和 Continue 语句总是可以分解的信号。
例如,我们有一个简单的搜索任务。找到目标并执行一些业务逻辑,或者什么都不做。

func processData(data []int, target int) {
   
    for i, value := range data {
   
        if value == target {
   
            performActionForTarget(data[i])
            break
        }
    }
}

你应该始终记住,使用 break 操作符并不能保证整个数组都会被处理。这对性能有好处,因为我们丢弃了不必要的迭代,但对代码支持和可读性不利。因为我们永远不知道程序会在列表的开头还是结尾停止。
在某些情况下,带有子任务的简单功能可能会破坏这段代码。

func processData(data []int, target int, subtask int) {
   
    for i, value := range data {
   
        if value == subtask {
   
            performActionForSubTarget(data[i])
        }
        if value == target {
   
            performActionForTarget(data[i])
            break
        }
    }
}

这样我们实际上可以拆出一个 find 的方法:

func processData(data []int, target int, subTarget int) {
   
    found := findTarget(data, target)
    if found > notFound {
   
        performActionForTarget(found)
    }

    found = findTarget(data, subTarget)
    if found > notFound {
   
        performActionForSubTarget(found)
    }
}

const notFound = -1

func findTarget(data []int, target int) int {
   
    if len(data) == 0 {
   
        return notFound
    }

    for _, value := range data {
   
        if value == target {
   
            return value
        }
    }

    return notFound
}

同样的逻辑,但是拆分成更细粒度的方法,也有精确的返回语句,可以很容易地通过测试来实现。
continue 操作
该操作符与 break 类似。为了正确阅读代码,您应该牢记它对操作顺序的具体影响。

func processWords(words []string, substring string) {
   
    for _, word := range words {
   
        if !strings.Contains(word, substring) {
   
            continue
        }
        
        // do some buisness logic
        performAction(word)
    }
}

Continue 使得这种简单的流程变得有点难以理解。
让我们写得更简洁些:

func processWords(words []string, substring string) {
   
    for _, word := range words {
   
        if strings.Contains(word, substring) {
   
            performAction(word)
        }
    }
}

相关推荐

  1. Go 重构尽量避免使用 else、break continue

    2023-12-22 07:02:08       59 阅读
  2. mysql:尽量避免使用select *语句

    2023-12-22 07:02:08       56 阅读
  3. Go使用循环时使用BreakContinue语句

    2023-12-22 07:02:08       58 阅读
  4. RabbitMQ避免重复消费

    2023-12-22 07:02:08       81 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-22 07:02:08       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-22 07:02:08       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-22 07:02:08       87 阅读
  4. Python语言-面向对象

    2023-12-22 07:02:08       96 阅读

热门阅读

  1. 在gitlab下用ssh克隆项目到Ubuntu

    2023-12-22 07:02:08       65 阅读
  2. vue3+vite+ts父子组件之间的传值

    2023-12-22 07:02:08       73 阅读
  3. Matlab数值计算常用命令

    2023-12-22 07:02:08       59 阅读
  4. 第九章 数据可视化—pyecharts

    2023-12-22 07:02:08       59 阅读
  5. python 神经网络归纳

    2023-12-22 07:02:08       67 阅读
  6. 2312llvm,04后端上

    2023-12-22 07:02:08       59 阅读
  7. 神经网络:数据预处理知识点

    2023-12-22 07:02:08       52 阅读
  8. 202312实战面试

    2023-12-22 07:02:08       65 阅读
  9. 人工智能 RL 算法边缘服务器

    2023-12-22 07:02:08       43 阅读