跳至主要内容

使用 GitHub Copilot 重构代码

利用 Copilot 人工智能帮助你快速有效地重构代码。

简介

代码重构是在不改变其行为的情况下重组现有代码的过程。重构的好处包括提高代码可读性、降低复杂性、使代码更易于维护以及更容易添加新功能。

本文提供了一些在 IDE 中使用 Copilot 重构代码的想法。

注意

本文包含示例回复。GitHub Copilot 聊天可能会提供与此处显示的不同的回复。

理解代码

在修改现有代码之前,应确保理解其用途和当前的工作方式。Copilot 可以帮助你做到这一点。

  1. 选择 IDE 编辑器中的相关代码。

  2. 打开内联聊天

    • **在 VS Code 中:** 按 Command+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • **在 Visual Studio 中:** 按 Alt+/.
    • **在 JetBrains IDE 中:** 按 Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 在内联聊天的输入框中,输入正斜杠 (/)。

  4. 在下拉列表中,选择 **解释 /explain** 并按 Enter

  5. 如果 Copilot 返回的解释超过几行,请点击 **在聊天中查看** 以便于阅读解释。

优化低效代码

Copilot 可以帮助你优化代码——例如,使代码运行速度更快。

示例代码

在下面两节中,我们将使用以下 bash 脚本示例来演示如何优化低效代码

#!/bin/bash

# Find all .txt files and count lines in each
for file in $(find . -type f -name "*.txt"); do
    wc -l "$file"
done

使用 Copilot 聊天面板

Copilot 可以告诉你代码(例如 bash 脚本示例)是否可以优化。

  1. 选择 `for` 循环或文件的全部内容。

  2. 通过点击活动栏中的聊天图标或使用键盘快捷键打开 Copilot 聊天。

    • **VS Code 和 Visual Studio:** Control+Command+i (Mac) / Ctrl+Alt+i (Windows/Linux)
    • **JetBrains:** Control+Shift+c
  3. 在聊天面板底部的输入框中,输入:这段脚本可以改进吗?

    Copilot 将回复一个建议,使代码更高效。

  4. 要应用建议的更改

    • **在 VS Code 和 JetBrains 中:** 将鼠标悬停在聊天面板中的建议上,然后点击 **插入到光标处** 图标。

      Screenshot of the 'Insert at cursor' icon in the Copilot Chat panel.

    • **在 Visual Studio 中:** 点击 **预览**,然后在比较视图中点击 **接受**。

使用 Copilot 内联聊天

或者,如果你已经知道现有代码(例如 bash 脚本示例)效率低下

  1. 选择 `for` 循环或文件的全部内容。

  2. 打开内联聊天

    • **在 VS Code 中:** 按 Command+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • **在 Visual Studio 中:** 按 Alt+/.
    • **在 JetBrains IDE 中:** 按 Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 输入 `optimize` 并按 Enter

    Copilot 会建议修改后的代码。例如

    find . -type f -name "*.txt" -exec wc -l {} +
    

    这比本文前面显示的原始代码更高效,因为使用 `-exec ... +` 允许 `find` 一次性将多个文件传递给 `wc`,而不是为找到的每个 `*.txt` 文件调用 `wc` 一次。

  4. 评估 Copilot 的建议,如果你同意更改

    • **在 VS Code 和 Visual Studio 中:** 点击 **接受**。
    • **在 JetBrains 中:** 点击预览图标(双箭头),然后点击应用所有差异图标(双尖括号)。

与所有 Copilot 建议一样,你应始终检查修改后的代码是否能无错误地运行并产生正确的结果。

清理重复代码

避免重复将使你的代码更容易修改和调试。例如,如果在文件的不同位置多次执行相同的计算,则可以将计算移动到函数中。

在以下非常简单的 JavaScript 示例中,相同的计算(商品价格乘以已售商品数量)在两个地方执行。

let totalSales = 0;

let applePrice = 3;
let applesSold = 100;
totalSales += applePrice * applesSold;

let orangePrice = 5;
let orangesSold = 50;
totalSales += orangePrice * orangesSold;

console.log(`Total: ${totalSales}`);

你可以要求 Copilot 将重复的计算移到函数中。

  1. 选择文件的全部内容。

  2. 打开内联聊天

    • **在 VS Code 中:** 按 Command+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • **在 Visual Studio 中:** 按 Alt+/.
    • **在 JetBrains IDE 中:** 按 Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 输入:将重复的计算移到函数中 并按 Enter

    Copilot 会建议修改后的代码。例如

    function calculateSales(price, quantity) {
      return price * quantity;
    }
    
    let totalSales = 0;
    
    let applePrice = 3;
    let applesSold = 100;
    totalSales += calculateSales(applePrice, applesSold);
    
    let orangePrice = 5;
    let orangesSold = 50;
    totalSales += calculateSales(orangePrice, orangesSold);
    
    console.log(`Total: ${totalSales}`);
    
  4. 评估 Copilot 的建议,如果你同意更改

    • **在 VS Code 和 Visual Studio 中:** 点击 **接受**。
    • **在 JetBrains 中:** 点击预览图标(双箭头),然后点击应用所有差异图标(双尖括号)。

与所有 Copilot 建议一样,你应始终检查修改后的代码是否能无错误地运行并产生正确的结果。

使代码更简洁

如果代码过于冗长,则难以阅读和维护。Copilot 可以建议所选代码的更简洁版本。

在以下示例中,这段 Python 代码输出矩形和圆形的面积,但可以写得更简洁

def calculate_area_of_rectangle(length, width):
    area = length * width
    return area

def calculate_area_of_circle(radius):
    import math
    area = math.pi * (radius ** 2)
    return area

length_of_rectangle = 10
width_of_rectangle = 5
area_of_rectangle = calculate_area_of_rectangle(length_of_rectangle, width_of_rectangle)
print(f"Area of rectangle: {area_of_rectangle}")

radius_of_circle = 7
area_of_circle = calculate_area_of_circle(radius_of_circle)
print(f"Area of circle: {area_of_circle}")
  1. 选择文件的全部内容。

  2. 打开内联聊天

    • **在 VS Code 中:** 按 Command+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • **在 Visual Studio 中:** 按 Alt+/.
    • **在 JetBrains IDE 中:** 按 Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 输入:使这段代码更简洁 并按 Enter

    Copilot 会建议修改后的代码。例如

    import math
    
    def calculate_area_of_rectangle(length, width):
      return length * width
    
    def calculate_area_of_circle(radius):
      return math.pi * (radius ** 2)
    
    print(f"Area of rectangle: {calculate_area_of_rectangle(10, 5)}")
    print(f"Area of circle: {calculate_area_of_circle(7)}")
    
  4. 评估 Copilot 的建议,如果你同意更改

    • **在 VS Code 和 Visual Studio 中:** 点击 **接受**。
    • **在 JetBrains 中:** 点击预览图标(双箭头),然后点击应用所有差异图标(双尖括号)。

与所有 Copilot 建议一样,你应始终检查修改后的代码是否能无错误地运行并产生正确的结果。

拆分复杂的代码单元

执行多个操作的大型方法或函数比专注于执行特定操作的较小、较简单的函数提供的重用机会更少。它们也可能更难以理解和调试。

Copilot 可以帮助你将复杂的代码块拆分为更适合重用的较小单元。

以下 Python 代码是一个非常简单的示例,但它展示了将单个函数拆分为执行特定操作的两个函数的原理。

import pandas as pd
from pandas.io.formats.style import Styler

def process_data(item, price):
    # Cleanse data
    item = item.strip()  # Strip whitespace from item
    price = price.strip()  # Strip whitespace from price
    price = float(price) # Convert price to a float
    # More cleansing operations here

    # Create and print a DataFrame
    data = {'Item': [item], 'Price': [price]}
    df = pd.DataFrame(data)
    print(df.to_string(index=False))

# Example usage
item = "   Apple "
price = " 1.25"
process_data(item, price)

要拆分 `process_data` 函数

  1. 将光标放在函数名称中。

  2. 打开内联聊天

    • **在 VS Code 中:** 按 Command+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • **在 Visual Studio 中:** 按 Alt+/.
    • **在 JetBrains IDE 中:** 按 Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 输入:拆分成两个单独的函数:一个用于数据清洗,另一个用于打印 并按 Enter

    Copilot 会建议修改后的代码。例如

    def cleanse_data(item, price):
      # Cleanse data
      item = item.strip()  # Strip whitespace from item
      price = price.strip()  # Strip whitespace from price
      price = float(price)  # Convert price to a float
      return item, price
    
    def print_data(item, price):
      # Create and print a DataFrame
      data = {'Item': [item], 'Price': [price]}
      df = pd.DataFrame(data)
      print(df.to_string(index=False))
    
    def process_data(item, price):
      item, price = cleanse_data(item, price)
      print_data(item, price)
    

    注意

    上面显示的示例建议用三个函数替换现有函数。第三个函数只是调用其他两个函数,并允许调用 `process_data` 函数的现有代码。

  4. 评估 Copilot 的建议,如果你同意更改

    • **在 VS Code 和 Visual Studio 中:** 点击 **接受**。
    • **在 JetBrains 中:** 点击预览图标(双箭头),然后点击应用所有差异图标(双尖括号)。

与所有 Copilot 建议一样,你应始终检查修改后的代码是否能无错误地运行并产生正确的结果。

重写条件代码以提高可读性

通常有几种方法可以编写根据各种条件执行或不执行的代码。某些条件结构比其他结构更适合特定用例,并且选择替代条件结构有时可以使代码更易于阅读。

此 Java 方法使用一系列 `if` 和 `else if` 语句来确定要执行的操作

public String getSound(String animal) {
  if (animal == null) {
      System.out.println("Oops! A null animal?");
  } else if (animal.equalsIgnoreCase("Dog")) {
      return "Bark";
  } else if ( animal.equalsIgnoreCase("Cat")) {
      return "Meow";
  } else if ( animal.equalsIgnoreCase("Bird")) {
      return "Tweet";
  }
  return "Unknown";
}

`switch` 语句可能是应用相同逻辑的更好方法。

  1. 将光标放在方法名称中。

  2. 打开内联聊天

    • **在 VS Code 中:** 按 Command+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • **在 Visual Studio 中:** 按 Alt+/.
    • **在 JetBrains IDE 中:** 按 Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 输入:重写条件以使用 switch 并使用 Java 21 语法和 null case,还要添加文档并提供更好的函数名称

    这演示了如何使用单个提示来要求 Copilot 进行多项更改。

  4. Enter

    Copilot 会建议修改后的代码。例如

    /**
     * Retrieves the sound made by a given animal.
     *
     * @param animal The name of the animal.
     * @return The sound made by the animal, or "Unknown" if the animal is not recognized.
     */
    public String getAnimalSound(String animal) {
        return switch (animal) {
            case null -> {
                System.out.println("Oops! A null animal?");
                yield "Unknown";
            }
            case String a when a.equalsIgnoreCase("Dog") -> "Bark";
            case String a when a.equalsIgnoreCase("Cat") -> "Meow";
            case String a when a.equalsIgnoreCase("Bird") -> "Tweet";
            default -> "Unknown";
        };
    }
    
  5. 评估 Copilot 的建议,如果你同意更改

    • **在 VS Code 和 Visual Studio 中:** 点击 **接受**。
    • **在 JetBrains 中:** 点击预览图标(双箭头),然后点击应用所有差异图标(双尖括号)。

与所有 Copilot 建议一样,你应始终检查修改后的代码是否能无错误地运行并产生正确的结果。

重新格式化代码以使用不同的结构

假设你在 JavaScript 中有此函数

function listRepos(o, p) {
 return fetch(`https://api.github.com/orgs/${o}/repos?per_page=${parseInt(p)}`)
   .then((response) => response.json())
   .then( (data) => data);
}

如果你的编码标准要求你对函数使用箭头表示法和描述性参数名称,则可以使用 Copilot 来帮助你进行这些更改。

  1. 将光标放在函数名称中。

  2. 打开内联聊天

    • **在 VS Code 中:** 按 Command+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • **在 Visual Studio 中:** 按 Alt+/.
    • **在 JetBrains IDE 中:** 按 Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 输入:使用箭头表示法和更好的参数名称 并按 Enter

    Copilot 会建议修改后的代码。例如

    const listRepos = (org, perPage) => {
      return fetch(`https://api.github.com/orgs/${org}/repos?per_page=${parseInt(perPage)}`)
        .then(response => response.json())
        .then(data => data);
    };
    

改进符号的名称

注意

  • 仅限 VS Code 和 Visual Studio。
  • 对该功能的支持取决于在你的 IDE 中为使用的语言安装相应的语言扩展。并非所有语言扩展都支持此功能。

精心选择的名称可以帮助使代码更易于维护。VS Code 和 Visual Studio 中的 Copilot 可以建议变量或函数等符号的替代名称。

  1. 将光标放在符号名称中。

  2. F2

  3. 仅限 Visual Studio:Ctrl+空格键

    Copilot 会建议替代名称。

    Screenshot of a dropdown list in VS Code giving alternatives for a symbol name.

  4. 在下拉列表中,选择一个建议的名称。

    名称将在整个项目中更改。