GPT-4审查和重构代码,有没有想过人工智能如何改变你的编码过程?在本指南中,我们将演示使用 ChatGPT 或 GPT-4 审查和重构代码的技术,并讨论一些限制并提供在编程工作流程中使用这些 LLM 的便利资源。

我们将从我们可以审查和重构的方式开始,对于每一种方式,您可能想要尝试不同的提示和提供的技术来释放 AI 驱动的代码改进的全部潜力。

注意:我将在内容中使用术语 GPT4,因为这是提示包含示例的当前模型。ChatGPT (GPT3.5) 的工作方式类似,可以互换使用。

使用 GPT-4 和 ChatGPT 重构代码

重构代码之所以至关重要,有几个原因:它增强了可读性和可维护性,使开发人员更容易理解和修改代码。它还有助于防止潜在的错误并确保您的代码符合既定的最佳实践。最终,重构可以带来更高效、可靠和健壮的软件。

GPT-4 可以为这一过程做出重大贡献。通过使用 GPT-4 审查和评估您的代码,您可以快速确定需要改进的地方并创建更简洁、更高效的代码。利用 GPT-4 的功能可以节省时间并减少流程中的人为错误,从而更加一致地遵守编码标准。

旧代码重构

您可以通过向 GPT-4 提供旧功能并要求其重构为现代编码实践来快速实现代码重构。

重构前:

function tempConvert(temp, scale) { // Vague function name
  var result = 0; // 'var' is so es2015
  if (scale == "C") { // Is this the correct way to compare strings?
    result = (temp - 32) * (5 / 9); // Magic numbers
  } else {
    result = (temp * (9 / 5)) + 32;
  }
  return result.toFixed(1) + "°" + (scale == "C" ? "F" : "C"); // This line feels a bit cluttered...
}

重构后:

/**
 * Converts a temperature between Celsius and Fahrenheit.
 * @param {number} temp - The temperature value to convert.
 * @param {string} scale - The temperature scale ('C' or 'F') to convert from.
 * @return {string} The converted temperature value, formatted with one decimal place and the appropriate unit.
 */
const tempConvert = (temp, scale) => {
  const isValidScale = scale === "C" || scale === "F";
  if (!isValidScale) {
    throw new Error("Invalid scale: must be 'C' or 'F'.");
  }

  const conversionFactor = 5 / 9; // <-- Note: This is not correct when 
  const result = scale === "C"
    ? (temp - 32) * conversionFactor
    : (temp * conversionFactor) + 32;

  const resultUnit = scale === "C" ? "F" : "C";
  return `${result.toFixed(1)}°${resultUnit}`;
}

在这次重构的版本中,GPT4 很快做出了以下改进:

  1. 添加了 JSDoc 注释
  2. 将函数转换tempConvert为箭头函数。
  3. 替换varconst不可变变量。
  4. 使用严格的相等性检查 ( ===) 进行字符串比较。
  5. 引入了一个常量来消除幻数。
  6. 使用模板文字简化了返回语句。

问题:

  • 逻辑:这种技术和提示擅长更新已知的编码实践,但可以对业务逻辑视而不见。下面的示例错误地重构了转换逻辑。

我们同样的提示来自……,它返回了一个更好的函数版本。这种两次或多次通过的方法非常有效。

...
function convertTemperature(temperature, scale) {
  const isValidScale = scale === "C" || scale === "F";
  if (!isValidScale) {
    throw new Error("Invalid scale: must be 'C' or 'F'.");
  }

  const convertedTemperature = scale === "C"
    ? (temperature * (9 / 5)) + 32
    : (temperature - 32) * (5 / 9);

  const resultUnit = scale === "C" ? "F" : "C";
  return `${convertedTemperature.toFixed(1)}°${resultUnit}`;
}

添加编码最佳实践或原则

您的组织或代码库可能使用您希望保留的某些编码实践和风格。对于这种情况,请向 GPT4 提供有关您希望其关注的特定编码实践或风格的说明。

迅速的: Review the following code and refactor it to make it more DRY and adopt the SOLID programming principles.

请注意,对于相同的输入,它采用了单一职责的 SOLID 编程原则,并将函数拆分为 3 个。与前面的“现代化”步骤不同,它没有将函数转换为箭头函数。

“通过将转换逻辑提取到单独的函数中,我们改进了代码对单一职责原则(SOLID 的一部分)的遵守,因为每个函数现在都有一个明确、集中的目的。”

function tempConvert(temp, scale) {
  const isValidScale = scale === "C" || scale === "F";
  if (!isValidScale) {
    throw new Error("Invalid scale: must be 'C' or 'F'.");
  }

  const result = scale === "C" ? celsiusToFahrenheit(temp) : fahrenheitToCelsius(temp);
  const resultUnit = scale === "C" ? "F" : "C";
  return `${result.toFixed(1)}°${resultUnit}`;
}

function celsiusToFahrenheit(temp) {
  const conversionFactor = 9 / 5;
  return (temp * conversionFactor) + 32;
}

function fahrenheitToCelsius(temp) {
  const conversionFactor = 5 / 9;
  return (temp - 32) * conversionFactor;
}

检测和修复错误

有时我们对我们的代码可能造成的漏洞或潜在问题视而不见。让 GPT-4 审查和解决代码问题可以为您节省的不仅仅是时间。

输入(有缺陷的)功能:

function updateTotalPrice(items, discountPercentage) {
  let totalPrice = 0;

  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    totalPrice += item.price * item.quantity;
  }

  // Potential error: discountPercentage is not validated or checked for boundary conditions
  const discount = totalPrice * (discountPercentage / 100);
  totalPrice -= discount;

  return totalPrice;
}

输出:

function updateTotalPrice(items, discountPercentage) {
  // Fix 1: Validate input parameters
  if (!Array.isArray(items) || typeof discountPercentage !== 'number') {
    throw new Error('Invalid input parameters');
  }

  // Fix 2: Check for boundary conditions of discountPercentage
  if (discountPercentage < 0 || discountPercentage > 100) {
    throw new Error('Invalid discount percentage value. It should be between 0 and 100');
  }

  let totalPrice = 0;

  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    
    // Fix 3: Validate item properties and types
    if (!item.hasOwnProperty('price') || !item.hasOwnProperty('quantity') || 
        typeof item.price !== 'number' || typeof item.quantity !== 'number') {
      throw new Error('Invalid item properties');
    }

    totalPrice += item.price * item.quantity;
  }

  const discount = totalPrice * (discountPercentage / 100);
  totalPrice -= discount;

  return totalPrice;
}

GPT-4 所做的更改:

  1. 添加了输入参数验证以确保 items 是一个数组并且 discountPercentage 是一个数字。
  2. 检查 discountPercentage 的边界条件以确保它在 0-100 范围内。
  3. 添加了对项目属性及其类型的验证,以确保价格和数量是数字。

创建样板代码(*我的最爱)

开始新项目可能会很痛苦。GPT-4 不知道您的业务逻辑,但它可用于在第一天启动无聊的样板代码。这不是技术上的重构,但它很了不起,并且可以成为编程生命周期中流程的一部分。

创建单元测试

单元测试不仅对您的代码库很重要,而且它们可以成为快速验证 GPT-4 生成的任何内容的有用方法。

转译代码

您可能需要将代码从一种语言转换为另一种语言的原因有很多。您找到了一个存储库,其中包含您需要的另一种语言的代码,您正在移动代码库,或者您的老板可能阅读了一篇关于最新前端框架的文章,现在您正在转向{分裂的新库}。

在任何情况下,GPT-4 都可以通过简单的提示提供帮助。

给代码添加注释

如果您的代码不言自明但需要注释,这可以节省大量时间。

更好重构的技巧

就像生活中的许多事情一样,使用 GPT-4,你会得到你投入的东西。在这种情况下,提供更多的背景、说明和指导通常会产生更好的结果。

以下是改进代码重构的技巧和技巧的简短列表:

  • 拆分您的提示:尝试在多个步骤中分解您的提示和期望的结果。保持提示以获得单一结果已证明比组合提示产生更好的结果。例如,要求审查,然后根据审查响应要求重构。随着 LLM 增加其令牌限制,这可能会随着时间的推移变得不那么重要。
  • 举例:提供预期的输入、数据和输出以提高准确性质量。
  • 要具体:不要害怕准确地列出你想要什么、你知道什么、需要什么以及不包括什么。
  • 要求它反映:一种称为反射的技术已被证明可以提高 GPT4 的准确性。基本上问它“你为什么错了?” 或者让它反思和审查自己的回应。

多提示方法(提示链接)

为 GPT-4 编写提示很像编写函数。一套设计良好的提示是每个提示都有独立的关注点和单一的责任。这是更新、重构和审查一段代码的简单提示链。您可能不需要每个步骤。

您会注意到生成的函数与我们之前创建的非常不同。在流程的每个步骤中,我们要么改进代码,要么在我们的系统上运行代码之前验证其有效性。

注意:使用了与之前相同的输入函数,但在不同的模型和不同的日期运行。

1. 现代化并添加最佳实践

让 GPT-4 将您的代码重新编写成您想要的样式。如上所示,此步骤通常会以您想要的样式产生连贯的输出,但可能会引入错误,因此我们首先执行此步骤。

GPT-4 响应:

const tempConvert = (temp, scale) => { // More descriptive function name
  let result = 0; // Use 'let' instead of 'var'
  const fahrenheitToCelsius = (temp - 32) * (5 / 9);
  const celsiusToFahrenheit = (temp * (9 / 5)) + 32;

  if (scale === "C") { // Use strict equality operator (===) for comparison
    result = fahrenheitToCelsius;
  } else {
    result = celsiusToFahrenheit;
  }

  const convertedScale = scale === "C" ? "F" : "C";
  return `${result.toFixed(1)}°${convertedScale}`; // Use template literals for cleaner string concatenation
};

2. 审查逻辑错误和安全问题

审查您的代码并提出建议,以改进引入的任何逻辑或安全问题。重要的是我们不要求重构,只是要求重构背后的原因。

GPT-4 回应: 以下是一些改进tempConvert功能以解决逻辑问题并使其更健壮的建议:

  1. 输入验证:该函数不对提供的温度和比例参数执行任何输入验证。如果输入不是预期的格式,这可能会导致意外行为。为了解决这个问题,您可以添加输入验证检查
if (typeof temp !== 'number' || (scale !== 'C' && scale !== 'F')) {
  throw new Error('Invalid input. Temp must be a number and scale must be either "C" or "F".');
}
  1. 未处理的比例值:如果scale参数不是“C”或“F”,该函数仍将执行摄氏度到华氏度的转换,这可能会产生误导。您可以添加一个支票来处理这种情况:
if (scale === 'C') {
  result = fahrenheitToCelsius;
} else if (scale === 'F') {
  result = celsiusToFahrenheit;
} else {
  throw new Error('Invalid scale value. Scale must be either "C" or "F".');
}
  1. 代码可读性:为了提高可读性和可维护性,您可以将每次转换(华氏度到摄氏度和摄氏度到华氏度)的转换逻辑分成两个单独的函数。这将使代码更易于理解和维护:
const fahrenheitToCelsius = temp => (temp - 32) * (5 / 9);
const celsiusToFahrenheit = temp => (temp * (9 / 5)) + 32;

 验证建议(Reflexion)

验证提供的建议。如上所示,反射是一种强大的技术,可以提高初始建议的准确性并尝试消除任何幻觉。

这并不总是必需的,但如果您对任何建议不确定,则值得询问。在我们的示例中,它只是重复相同的建议。在这种情况下,它没有提供任何额外信息,但确实确认了这些建议是有效的。

GPT-4 回复:对于任何混淆,我深表歉意。在查看tempConvert我之前提供的功能后,我意识到我在之前的回复中犯了一个错误。我已经在提供的函数中加入了严格相等 (===) 和模板文字。

但是,我最初的建议仍然适用于提高函数的稳健性和可读性。总而言之,以下是更新后的建议:

  1. 输入验证:tempscale参数添加输入验证检查以确保它们具有预期的类型和值: {code}
  1. 未处理的比例值:scale处理参数不是“C”或“F”的情况以避免误导性转换: {code}
  1. 代码可读性:将转换逻辑分离成两个独立的函数,以提高可读性和可维护性: {code}

我希望这能消除任何困惑。上述建议应增强功能的逻辑流程tempConvert,并使其在处理各种输入场景时更加健壮。

4.编写代码

结合您的评论、建议和反馈,让 GPT-4 编写您喜欢的新功能。

const fahrenheitToCelsius = temp => (temp - 32) * (5 / 9);
const celsiusToFahrenheit = temp => (temp * (9 / 5)) + 32;

const tempConvert = (temp, scale) => {
  if (typeof temp !== 'number' || (scale !== 'C' && scale !== 'F')) {
    throw new Error('Invalid input. Temp must be a number and scale must be either "C" or "F".');
  }

  let result = 0;

  if (scale === 'C') {
    result = fahrenheitToCelsius(temp);
  } else if (scale === 'F') {
    result = celsiusToFahrenheit(temp);
  } else {
    throw new Error('Invalid scale value. Scale must be either "C" or "F".');
  }

  const convertedScale = scale === "C" ? "F" : "C";
  return `${result.toFixed(1)}°${convertedScale}`;
};

5. 创建测试

最后,我们要求它创建一些简单的 JavaScript 测试,我们可以在本地运行这些测试并验证我们奇特的新功能的结果。

GPT-4 响应:这里有两个针对该函数的简单普通 JavaScript 测试tempConvert,一个预计会通过,另一个预计会失败:

const testTempConvertPass = () => {
  const inputTemp = 32;
  const inputScale = 'C';
  const expectedResult = '0.0°C';

  const result = tempConvert(inputTemp, inputScale);

  if (result === expectedResult) {
    console.log('Test pass: tempConvert with valid input');
  } else {
    console.error(`Test fail: tempConvert with valid input. Expected ${expectedResult} but got ${result}`);
  }
};

const testTempConvertFail = () => {
  try {
    const inputTemp = 32;
    const inputScale = 'InvalidScale';
    tempConvert(inputTemp, inputScale);
    console.error('Test fail: tempConvert with invalid input should throw an error');
  } catch (error) {
    console.log('Test pass: tempConvert with invalid input');
  }
};

// Run the tests
testTempConvertPass();
testTempConvertFail();

限制

这篇文章非常支持 AI,但是这些模型并不完美,并且不能(还)准确地复制业务逻辑等。以下是使用 GPT-4 审查或重构代码时需要注意和避免的事项列表:

  • 它可能(自信地)错了: GPT4 经过训练听起来很有说服力,但这并不意味着它总是正确的。另一篇关于使用 ChatGPT 重构 Golang 的精彩文章报告说“它摆脱了类型检查,并自信地解释说将非 int 值类型断言为 int 类型将返回 int 类型的零值,但这是不正确的,并且会恐慌’
  • 从长远来看,预先节省时间可能不值得:当然,GPT-4 可以在一分钟内为您生成 50 行代码,但如果它不适合您的代码库,最终可能需要 45 分钟来调试和调整它. 你最好自己写。
  • 它可能已经过时:技术世界发展迅速。“GPT-4 通常缺乏对绝大多数数据中断后发生的事件的了解(2021 年 9 月) ”。您可能会遇到任何新更新的库、框架或技术的问题。

使用GPT-4审查和重构代码的结论

人工智能驱动的编程只是一个新事物,但它会一直存在。如果使用得当,它可以节省时间并帮助我们编写更好的代码。我希望您喜欢这篇文章并掌握了一些新技能来提高您的编程效率或错误处理能力。

相关推荐

使用GPT-4开发游戏

使用GPT-4执行NLP(自然语言处理)任务

购物领券有优惠