身为程序员,除了寻求代码的正确性、健壮性之外,还需考虑代码的美观性。高雅的代码让人赏心悦目,而糟糕的代码让人直呼辣眼睛,恨不得把写代码的人拉过来当场责问,你为什么要这么写?!假如不关注代码的高雅性,还可能构成更严峻的后果——屎山。这是一个适当有滋味的词,足以见得人们对劣质代码的讨厌。

高雅的代码不仅是为了他人的身心健康,更是防止将来重看自己代码时还能够看得懂。

什么样的代码算是高雅的代码

高雅的代码是一种感觉,让人看了就觉得舒服 …..咳咳,打住。开个打趣,高雅的代码当然不是一个形而上学的问题。咱们能够从一下几个维度来评价代码的高雅性。

  1. 可读性:高雅的代码应当易于了解。它应当像故事一样能够流畅地阅览,使得其他开发者很容易就能了解它的功用和完成方法。

  2. 简洁性:高雅的代码应当防止不必要的复杂性。这意味着它防止了冗余的代码,而且尽可能的精简。

  3. 明确性:高雅的代码明确地表达了其目的。变量和函数的命名应当清晰明确,防止使用模糊不清或许有歧义的命名。

  4. 模块化和可重用性:高雅的代码能够很好地进行模块化,一起也供给了高度的可重用性。这意味着代码被组织成可独立运行且可轻松移植和复用的模块或组件。

  5. 健壮性和可扩展性:高雅的代码在面临异常情况时能够进行恰当的处理,而且具有良好的可扩展性,能够在不对现有代码进行大规模修正的情况下增加新的功用。

  6. 符合编程约好或风格攻略:每种编程言语或许项目通常都会有一套编程约好或许风格攻略,高雅的代码应当遵从这些约好或攻略,这不仅能够增强代码的可读性,还能够使得代码在整个项目中风格一致。

  7. 注释:尽管高雅的代码自身应当尽可能地自解释,但是在必要的当地增加适当的注释仍然是非常重要的。好的注释能够协助读者了解代码的功用和完成方法,以及在特定当地为什么要选用某种规划或许策略。

其间的每一个点都能够打开细讲,详细可见罗伯特马丁先生所著的《代码简洁之道》(《Clean Code》)

2年前我看过这本书,现在还记得里边讲的一些规矩,并沿用至今。

例如:

  • 一个函数只做一件小事
  • 命名要要表达满足的意义,哪怕长一点也不要紧
  • 不要写冗余的注释,冗余的注释和糟糕的代码一样糟蹋人的时刻

此外还可参考各大厂的编程标准攻略。例如:阿里巴巴编码标准(Java)、google-styleguide

如何写出漂亮、高雅的代码

代码的高雅性涉及方方面面,不是一朝一夕能够做到的,有些方面乃至需求有满足的经历之后才干做到。例如可重用性、可扩展性。这要求规划程序时有更多的考量。

但是有一点是敲代码的榜首天就要开始注意的,那便是简洁性。而现在,即便是刚触摸编程的新手也能很好的处理这个问题。——想必我们现已猜到了,那便是凭借大言语模型。

事实上对于一个刚开始触摸编程或许触摸不久的同学来讲,ta并不清楚什么是好代码或许坏代码。直到ta看到他人写的好代码,并开始刻意仿照,才干逐渐的改进自己的代码。其实这便是写出高雅代码的两个最关键因素了:仿照。但还有一个细节,先卖个关子。

这就如同高中学习写作文,通过阅览优异的作文,然后去仿照,一朝一夕就能写出好作文了。但,真的是这样吗?我记得我高中也看了不少好的作文,为什么我仍是写得稀烂。现在换个方法,我辛辛苦苦写一篇稀烂(40分)的作文,然后交给教师,教师不改动我的结构,只是通过删去和修正句子,写一篇55分的作文给我,并告诉我为什么要这么改动,然后我再去仿照,就这么一向重复训练,我相信我必定能写出好的作文。或许你会说假如结构从一开始就很糟糕,内部的细节再好也不行,那是结构层面问题了,相同能够找大量同类型的作文来仿照。直到有一天不管是结构仍是细节都能信手拈来,自然能写好一篇作文。

想必我们现已明白我刚才说的那个细节是什么了,那便是:有针对的仿照,写细节的时候就仿照细节,写结构的时候就仿照结构,这样的前进才是最快的。

这个问题最难的当地便是首先你能找到一个教师,ta来帮你修正,告诉你什么是好的。现在大言语模型便是这个教师。把你写好的代码丢给它,让它帮你改,改完之后再仿照。

详细演示

经常听一些老程序员吐槽所谓的if else垃圾代码,每一个程序员在刚开始编程时不可防止的也写过很多这样的代码。虽说人们吐槽它欠好,但很少听到人们解释它为什么欠好。

事实上if else是代码中不可或缺的逻辑部分,没有任何一个程序能够缺少条件语句。而糟糕的代码往往含有大量、零星的if else。这样的代码最大的问题在于:

if是某个特定的情况下才履行,而大量零星的if else就意味着将代码的逻辑打散了(假如对这样的代码画一个流程图就更显然了)。而每个人思考问题的逻辑是不一样的,让他人跟着零星的逻辑走是一件很苦楚的事。

为此我找来了曾经的代码作为演示:

榜首题:

如何写出漂亮、优雅的代码

我曾经的代码如下:

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        m, n = len(obstacleGrid), len(obstacleGrid[0])
        dp1 = [1] * n
        first_obstacle = -1
        # 独自处理榜首行
        for idx, num in enumerate(obstacleGrid[0]):
            if num == 1:
                first_obstacle = idx
                break
        if first_obstacle != -1:
            for col in range(first_obstacle, n):
                dp1[col] = 0
        for row in range(1, m):
            # 处理榜首列
            dp2 = []
            if obstacleGrid[row][0] == 1:
                dp2.append(0)
            else:
                dp2.append(dp1[0])
            for col in range(1, n):
                if obstacleGrid[row][col] == 1:
                    dp2.append(0)
                else:
                    dp2.append(dp2[-1] + dp1[col])
            dp1 = dp2.copy()
        return dp1[n-1]

上面的代码现已优化了空间复杂度,将二维dp压缩为一维dp,是一个正确的算法。

从逻辑上来讲:

  • 先独自处理了榜首行构成dp1

  • 在循环内部又独自处理榜首列

来看看chatGPT的优化:

如何写出漂亮、优雅的代码

  • 进一步优化空间
  • 一致一切行与列的操作,不必再独自处理榜首行榜首列

正如我前面所说,这儿减少了if else来处理特殊情况,毫无疑问要比我之前的代码高雅。

第二题:

如何写出漂亮、优雅的代码

曾经的代码:(注:此题可选用KMP算法取得更低的时刻复杂度,这不是这儿的要点)

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        i = 0
        while i < len(haystack):
            if haystack[i] == needle[0]:
                j, k = 0, i
                while j < len(needle) and k < len(haystack):
                    if haystack[k] != needle[j] :
                        break
                    k += 1
                    j += 1
                if j == len(needle):
                    return i
            i += 1
        return -1

chatGPT的优化:

如何写出漂亮、优雅的代码

这儿现已确保haystack[i + j]不会越界,所以能够进一步优化为

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        for i in range(len(haystack) - len(needle) + 1):
            if all(haystack[i + j] == needle[j] for j in range(len(needle))):
                return i
        return -1
  • 将原本的三个指针优化为两个
  • 选用all语法看起来更简洁

仿照

有了例1的纠正,下面一道题就能够进行仿照

如何写出漂亮、优雅的代码


class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0]) if grid else 0
        dp = [0] * n
        for row in range(m):
            for col in range(n):
                if col == 0:
                    dp[col] += grid[row][col]
                elif row == 0:
                    dp[col] = dp[col - 1] + grid[row][col]
                else:
                    dp[col] = grid[row][col] + min(dp[col-1], dp[col])
        return dp[n-1]

再回头来看看我曾经的代码:

如何写出漂亮、优雅的代码

总结

这篇博客要点解说假如确保函数内部代码的高雅性,这是一个细粒度的层面,但是相同非常重要。

给出prompt:

请对下面的代码进行优化,以进步代码的可读性和简洁性,并确保算法的正确性:

code …

请修正以上代码,确保代码的逻辑和功用不变,并优化其结构、命名和注释等方面以进步代码的可读性和简洁性。

最后,言语模型的优化并不能确保必定正确,有时候还会发生负优化,我们要谨慎选用。

与君共勉。