Skip to main content

使用 GitHub Copilot 重构代码

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

介绍

重构代码是重新构建现有代码的过程,而不更改其外部行为的过程。 重构的好处包括提高代码可读性、降低复杂性、使代码更易于维护,并可以更轻松地添加新功能。

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

Note

本文中包含示例响应。 GitHub Copilot Chat 可能会为你提供与此处所示不同的响应。

了解代码

在修改现有代码之前,应确保了解其用途及其当前工作原理。 Copilot 可以帮助你完成此操作。

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

  2. 打开内联聊天:

    • 在 VS Code 中: 按“命令”+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • 在 Visual Studio 中:Alt+/
    • 在 JetBrains IDEs 中: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 Chat 面板

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

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

  2. 单击活动栏中的聊天图标或使用键盘快捷方式打开 Copilot Chat:

    • VS Code 和 Visual Studio:控制+命令+i (Mac) / Ctrl+Alt+i (Windows/Linux)
    • JetBrainsControl+Shift+c
  3. 在聊天面板底部的输入框中,键入:Can this script be improved?

    Copilot 回复一项将提高代码效率的建议。

  4. 若要应用建议的更改,请执行以下操作:

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

      Copilot Chat 面板中“在光标处插入”图标的屏幕截图。

    • 在 Visual Studio 中: 单击“预览”,然后在比较视图中单击“接受”

使用 Copilot 内联聊天

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

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

  2. 打开内联聊天:

    • 在 VS Code 中: 按“命令”+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • 在 Visual Studio 中:Alt+/
    • 在 JetBrains IDEs 中:Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 键入 optimize,然后按“Enter”

    Copilot 建议使用修改的代码。 例如:

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

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

  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 中: 按“命令”+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • 在 Visual Studio 中:Alt+/
    • 在 JetBrains IDEs 中:Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 键入 move repeated calculations into functions,然后按“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 中: 按“命令”+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • 在 Visual Studio 中:Alt+/
    • 在 JetBrains IDEs 中:Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 键入 make this more concise,然后按“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 中: 按“命令”+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • 在 Visual Studio 中:Alt+/
    • 在 JetBrains IDEs 中:Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 键入 split into 2 separate functions: one for cleansing data, the other for printing,然后按“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)
    

    Note

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

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

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

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

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

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

此 Java 方法使用一系列 ifelse 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 中: 按“命令”+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • 在 Visual Studio 中:Alt+/
    • 在 JetBrains IDEs 中:Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 键入:rewrite the condition to use a switch and use Java 21 syntax with null case, but also add documentation and provide a better function name

    这演示了如何使用单个提示来要求 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 中: 按“命令”+i (Mac) 或 Ctrl+i (Windows/Linux)。
    • 在 Visual Studio 中:Alt+/
    • 在 JetBrains IDEs 中:Control+Shift+i (Mac) 或 Ctrl+Shift+g (Windows/Linux)。
  3. 键入 use arrow notation and better parameter names,然后按“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);
    };
    

改进符号的名称

Note

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

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

  1. 将光标置于符号名称中。

  2. 按“F2”

  3. 仅 Visual Studio:Ctrl+Space

    Copilot 建议使用可选名称。

    VS Code 中下拉列表的屏幕截图,其中提供了符号名称的可选名称。

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

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