代码多线索化考虑得并不充分_简洁的代码并不总是干净的代码-这就是为什么

代码多线索化考虑得并不充分

As developers, we want to write code that works, is readable, efficient, concise, and if possible, reusable.

作为开发人员,我们希望编写有效,可读,高效,简洁,并且在可能的情况下可重用的代码。

When a lot of us think of clean code, we probably fall into the trap of thinking that less code is better code. While this is often the case, it's not always so.

当我们中许多人想到干净的代码时,我们可能会陷入这样的陷阱:更少的代码就是更好的代码。 尽管通常是这种情况,但并非总是如此。

If I can get the job done in a way that other developers can follow behind me and immediately (or at least easily) understand what I’ve done, that’s what I’ll do.

如果我能以其他开发人员可以跟随我的方式完成工作,并且立即(或至少轻松地)了解我的工作,那便是我要做的。

那么,什么是干净代码? (So, What Is Clean Code?)

These days it’s much more important that you and I can read the code efficiently than the device can (in most cases).

这些天来,您和我(在大多数情况下 )能比设备更有效地阅读代码更为重要

When I write code, my first objective is always to get the job done. Following that, I write code for human readability, then runtime complexity, then conciseness. Finally, if I can, I make the code easily reusable.

在编写代码时,我的首要目标始终是完成工作。 然后,我编写代码以提高可读性,然后是运行时复杂性,然后是简洁性。 最后,如果可以的话,我可以使代码易于重用。

If I must write code in such a way that it’s no longer easily human readable in order to satisfy a complexity/time or re-usability requirement, you can be sure that it will be very well documented.

如果为了满足复杂性/时间或可重用性的要求,我必须以不再易于阅读的方式编写代码,则可以确保对它进行了很好的记录。

我认为干净代码的示例 (An Example of What I Consider Clean Code)

I was recently given a challenge to find a sole odd number in an array of even numbers, or vice-versa. I was given an array of Integers as the input, and I didn't know whether or not it contained odd or even numbers. There would definitely be a minimum of 3 values in the array and only one of them would be odd/even.

最近,我面临挑战,要在偶数数组中找到唯一的奇数,反之亦然。 我得到了一个整数数组作为输入,但我不知道它是否包含奇数或偶数。 数组中肯定至少要有3个值,而其中只有一个是奇数/偶数。

这是我的解决方案: (This was my solution:)

func findOutlier(_ array: [Int]) -> Int {
  //since we're guaranteed to have 3 values, grab the first 3
  let parityArr = [
      array[0],
      array[1],
      array[2]
  ]
  //track any odd or even numbers found in parityArr || O(1) - (technically O(n) but we know the input won't grow)
  var odd = 0
  var even = 0
  for num in parityArr {
     //number is even
     if num % 2 == 0 {
         even += 1
     //number is odd
     } else {
         odd += 1
     } 
  }
  //track and test whether there were more odd or even numbers in the array
  var isEven = false
  if even > odd {
      isEven = true
  }  
  //return the first match that's an outlier based on the array containing more even or more odd numbers || O(n) - we don't know the input size 
  if isEven {
      return array.first(where: ({ $0 % 2 != 0 }))!
  } else {
      return array.first(where: ({ $0 % 2 == 0 }))!
  }
}

If you’ll notice, I left notes that included the runtime complexity, or how efficiently an algorithm scales — even though that’s probably pretty obvious if you care about that sort of thing. I also left notes on what the input size was of a given operation (even though again, it’s pretty obvious).

如果您会注意到,我留下了一些注释,其中包括运行时的复杂性或算法扩展的效率-即使您关心这种事情,这可能很明显。 我还留下了关于给定操作的输入大小的注释(即使再次出现,也很明显)。

什么时候要简洁,什么时候要“写出来” (When To Be Concise and When To "Write It Out")

There are instances where concise code can reduce compilation time, or runtime execution, or a number of other things. Again though, my chief concern is whether or not the next developer can read it, follow along easily, and work with it.

在某些情况下,简洁的代码可以减少编译时间,运行时执行或其他许多事情。 同样,我主要关心的是下一个开发人员是否可以阅读,轻松地进行学习并与之合作。

过于简洁如何影响可读性? (How Can Being Too Concise Affect Readability?)

In my return for instance, I could've made this line return array.first(where: ({ $0 % 2 != 0 }))! into a for loop where I returned the first match. But it would be doing the exact same thing, and because of the way this is named, I think it's just as readable.

以我的回报为例,我可以使该行return array.first(where: ({ $0 % 2 != 0 }))! 进入for循环,我返回了第一场比赛。 但这将做完全相同的事情,并且由于其命名方式,我认为它也具有可读性。

But maybe you don't understand closure syntax, or your coworker doesn't. That's OK - spell it out. I chose not to, because this appears just as readable to me yet is more concise.

但是也许您不了解闭包语法,或者您的同事不了解。 没关系-讲清楚。 我选择不这样做,因为这对我来说可读性更强。

return array.first(where: { ... "written out" is:

return array.first(where: { ... “写出”为:

for num in array {
    if num %2 !=0 {
        return num
    }
}

There are a few opportunities to make the code in this example more concise, and still remain readable for the majority of developers.

有一些机会可以使此示例中的代码更简洁,并且对于大多数开发人员而言仍保持可读性。

As such, I could've also made this block:

这样,我也可以完成以下步骤:

var isEven = false
if even > odd {
    isEven = true
}

Look more like this:

看起来更像这样:

var isEven = even > odd

var isEven = even > odd

The return block noted above could be made into a 1-line check using the ternary operator, but there seem to be an increasing number of developers that aren’t familiar with the ternary operator. I think an if/else block is more readable in most cases as well:

可以使用三元运算符将上面提到的return块变成1行检查,但是似乎有越来越多的开发人员不熟悉三元运算符。 我认为在大多数情况下,if / else块也更具可读性:

if isEven {
    return array.first(where: ({ $0 % 2 != 0 }))!
} else {
    return array.first(where: ({ $0 % 2 == 0 }))!
}

return isEven ? array.first(where: {$0 %2 != 0}) : array.first(where: {$0 %2 == 0})

return isEven ? array.first(where: {$0 %2 != 0}) : array.first(where: {$0 %2 == 0})

Personally, I just find both of those concise one line statements to be a little less easily readable - especially where the ternary operator is involved.

就我个人而言,我只是发现这两个简洁的单行语句不太容易阅读-特别是在涉及三元运算符的地方。

At any rate, I was pretty satisfied with my solution – it passed all of the unit tests, it was pretty efficient, and it was human readable. But when I saw other people’s solutions, at first I was a little ashamed of my rudimentary one…

无论如何,我对我的解决方案感到非常满意–它通过了所有的单元测试,非常有效,并且易于阅读。 但是,当我看到其他人的解决方案时,起初我对我的基本解决方案感到ham愧……

A lot of them were using filter, a lot of them were using the ternary operator. Most of them were a lot more concise.

他们中的许多人使用过滤器,其中许多人使用三元运算符。 他们大多数人都更加简洁。

过于简洁的例子 (An Example of Being Too Concise)

The top-rated answer was 2 lines of code that I had a hard time reading at first – but that code will definitely get the job done. It may be more efficient than my solution in some cases, and it is obviously very concise:

评分最高的答案是我最初很难读的两行代码,但是这些代码一定可以完成工作。 在某些情况下,它可能比我的解决方案更有效,并且它非常简洁:

func findOutlier(_ array: [Int]) -> Int {
    let odd = array.filter{$0 % 2 != 0}
    return odd.count > 1 ? array.filter{$0 % 2 == 0}[0] : odd[0]
}

Both of those examples meet the first criteria of writing clean (or really, any) code - they work. They're both also concise, though my solution could be more concise. At first glance, I thought the more concise solution was great. It’s elegant, it’s efficient, and it’s… concise.

这两个示例都符合编写干净(或实际上,任何)代码的第一个条件-它们可以工作。 它们都同样简洁,尽管我的解决方案可能更简洁。 乍一看,我认为更简洁的解决方案很棒。 它优雅,高效,简洁。

Then I started to break up the return into an if/else and realized my solution is probably more efficient most of the time. I’m only ever iterating over the whole array once, and only if the parity outlier is the final number in the array.

然后,我开始将收益分成if / else,并意识到我的解决方案在大多数情况下可能更有效。 我只遍历整个数组一次,并且仅当奇偶校验离群值是数组中的最后一个数时。

It's still a good solution, but I wouldn't say it's great (or as many on the site noted - a best practice).

它仍然是一个很好的解决方案,但我不会说它很棒 (或网站上指出的很多-最佳实践)。

In the case of a majority even array in the concise solution, it would be filtered twice. Once to create the array called odd (which could also be named better)  — that’s the entire array being iterated over. Then again if it turns out not to be a majority odd array.

对于简洁解决方案中的多数偶数数组,将对其进行两次过滤。 一旦创建了一个名为奇数的数组(也可以命名为奇数),即遍历了整个数组。 如果事实证明不是多数派奇数数组,则再次。

This is no big deal if there are only 3 numbers. But given an array of 10,000 numbers, you’re looking at a chunk of time where your user is left waiting for something to compute that doesn’t need to be computed.

如果只有3个数字,这没什么大不了的。 但是给定一个由10,000个数字组成的数组,您正在查看用户需要等待大量时间来进行一些不需要计算的事情。

Another thing to note about my solution vs the concise solution is that my answer is returned as soon at it’s found in the array.

关于我的解决方案与简洁解决方案的另一件事要注意的是,一旦在数组中找到我的答案,就会立即返回。

Let’s say the input array was odd, and the even number was the first number in the array. In my solution, it would be computed and returned almost immediately, while in the concise solution, we’d be waiting for the entire array to be filtered before returning the answer.

假设输入数组是奇数,偶数是数组中的第一个数字。 在我的解决方案中,它将被立即计算并返回,而在简洁的解决方案中,我们将等待整个数组被过滤后再返回答案。

关于可重用性的注意事项 (A Note on Re-usability)

I touched on re-usability early on, but we haven't talked about it much. Code that's reusable means you can use it in more than just one situation.

我很早就谈到了可重用性,但是我们并没有谈论太多。 可重用的代码意味着您可以在多种情况下使用它。

This is one of the chief concerns of writing clean code, but only when it applies. We can do this by using parameters in functions that are flexible for different use cases, and other things that go along the lines of being able to use our code somewhere else without any or much modification.

这是编写简洁代码的主要问题之一,但前提是适用。 我们可以通过在函数中使用参数来实现此目的,这些函数可以灵活地适应不同的用例,并且可以进行其他事情而无需任何修改就可以在其他地方使用我们的代码。

But how can writing reusable code affect readability?I could've made this whole function generic. It would still meet the criteria, and would make it more reusable. We would be able to check any numeric type for example, but that wasn't in the scope of this project, and doing so would make it less readable if you aren't familiar with generic syntax.

但是编写可重用代码如何影响可读性? 我可以使整个函数通用。 它仍将符合标准,并使它更可重用。 例如,我们将能够检查任何数字类型,但这不在本项目的范围内,并且如果您不熟悉通用语法,这样做将使它的可读性降低。

保持清洁避免掉落 (Keeping It Clean Avoids Pitfalls)

One of the pitfalls of writing code that’s a little too concise is that it’s difficult to account for edge cases. This is because it makes it more difficult to to see the “moving pieces” at a glance.

过于简洁的编写代码的陷阱之一是很难考虑边缘情况。 这是因为,这样一眼便很难看清“运动片”。

I’m definitely not saying my solution is perfect. I can already see one way I could make it more efficient (we could skip the final O(n) operation in some cases) and still remain readable.

我绝对不是说我的解决方案是完美的。 我已经看到一种提高效率的方法(在某些情况下,我们可以跳过最后的O(n)操作)并且仍然保持可读性。

But the point is, I can come back to this code at any time in the near or distant future, easily see how it's working, and how I can make it better.

但关键是,我可以在不久或将来的任何时间返回此代码,轻松了解它的工作方式以及如何使其变得更好。

Just remember, there’s a lot that goes into writing clean code. Clean doesn’t just mean concise! Write your code so other developers can work with it — every human that works on it will thank you.

请记住,编写干净的代码有很多事情要做。 清洁不仅仅是 简明扼要! 编写您的代码,以便其他开发人员可以使用它-从事此工作的每个人都会感谢您。

翻译自: https://www.freecodecamp.org/news/concise-code-isnt-always-clean-code/

代码多线索化考虑得并不充分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值