您如何看待一线功能?这不好吗? 我能想到的一个优点是它使代码更加全面(如果你为它选择一个好名字)。例如:
void addint(Set *S, int n)
{
(*S)[n/CHAR_SIZE] |= (unsigned char) pow(2, (CHAR_SIZE - 1) - (n % CHAR_SIZE));
}
我能想到的一个缺点是它会减慢代码的速度(将参数推送到堆栈,跳转到函数,弹出参数,执行操作,跳回代码 - 只有一行?)
将这些行放在函数中还是只将它们放在代码中更好?即使我们只使用它们一次?
顺便说一下,我没有发现任何关于这个的问题,所以请原谅我以前曾经问过这样的问题。答案 0 :(得分:25)
不要害怕单行功能!
许多程序员似乎都有关于1行功能的心理障碍,你不应该这样做。
如果它使代码更清晰,更清晰,则将该行提取到函数中。
效果可能不会受到影响。
在过去十年(或许可能更进一步)制作的任何体面编译器都会自动内联一个简单的1行函数。此外,1行C可轻松对应多行机器代码。您不应该假设即使在理论情况下,您会产生函数调用的全部开销,这与您的“一条小线”相比,这种开销很大。更重要的是,对您的应用程序的整体性能有重要意义。
抽象导致更好的设计。(即使是单行代码)
函数是抽象的,组件化的代码的主要构建块,它们不应该被忽略。如果在函数调用后面封装一行代码会使代码更具可读性,那就去做吧。即使在函数被调用一次的情况下也是如此。如果您发现对一行特定代码进行注释很重要,那么这是一个很好的代码味道,将代码移动到一个命名良好的函数可能会有所帮助。
当然,这个代码今天可能只有1行,但有多少种不同的执行相同功能的方法呢?在函数内部封装代码可以更容易地查看可用的所有设计选项。也许你的1行代码扩展为对web服务的调用,也许它变成了数据库查询,也许它变得可配置(例如,使用策略模式),也许你想切换到缓存由你的1-计算的值线。当您将1行代码解压缩到自己的函数中时,所有这些选项都更容易实现,更容易想到。
也许你的1行应该更多。
如果你有一大堆代码,很可能很多人将很多功能塞进一行,只是为了节省屏幕空间。将此代码迁移到函数时,可以减少这些压力,这可能会使您更倾向于将复杂的1-liner扩展为更简单的代码,从而占用多行(这可能会提高其可读性和可维护性)。
答案 1 :(得分:8)
我不喜欢将所有类型的逻辑和功能捆绑在一条线上。您显示的示例是一个混乱,可以分解为几行,使用有意义的变量名称并执行一个接一个的操作。
我强烈建议,在此类问题中,请this book: Robert C. Martin - Clean Code查看(购买,借用,(不)下载(免费)) 。每个开发人员都应该看一本书。
它不会立刻让你成为一个好的程序员,它不会阻止你在将来编写丑陋的代码,但是当你编写丑陋的代码时它会让你意识到它。它将迫使您以更批判的眼光看待您的代码,并使您的代码像报纸一样可读。
答案 2 :(得分:5)
如果多次使用,肯定使它成为一个函数,并让编译器执行内联(可能在函数定义中添加“inline”)。 (<关于过早优化的常见建议在这里>)
答案 3 :(得分:5)
由于您的示例似乎使用了C(++)语法,因此您可能需要阅读inline functions,这样可以消除调用简单函数的开销。此关键字仅建议编译器,它可能不会内联您标记的所有函数,并且可能选择内联未标记的函数。
在.NET中,JIT会内联它认为合适的内联方法,但你无法控制它为什么或什么时候这样做,但是(据我所知),调试版本永远不会内联,因为这会阻止源代码匹配已编译的申请表。
答案 4 :(得分:1)
一行函数没有错。如上所述,编译器可以内联函数,这将消除任何性能损失。
函数也应优先于宏,因为它们更容易调试,修改,读取并且不太可能产生意外的副作用。
如果只使用一次那么答案就不那么明显了。将其移动到一个函数可以使调用函数更简单&通过将一些复杂性转移到新功能中来更清楚。
答案 5 :(得分:0)
如果你使用该函数中的代码3次或更多次,那么我建议将它放在一个函数中。仅用于可维护性。
答案 6 :(得分:0)
用什么语言?如果你的意思是C,我也会使用inline
限定符。在C ++中,我可以选择inline
,boost.lamda
或者继续向lamdas提供C ++ 0x原生支持。
答案 7 :(得分:-1)
有时使用预处理器并不是一个坏主意:
#define addint(S, n) (*S)[n/CHAR_SIZE] |= (unsigned char) pow(2, (CHAR_SIZE - 1) - (n % CHAR_SIZE));
当然,您没有进行任何类型的检查,但在某些情况下,这可能很有用。宏有它们的缺点和优点,并且在少数情况下它们的缺点可以变得有利。我在适当的地方是宏的粉丝,但是由你来决定什么时候合适。在这种情况下,我会说出来,无论你最后做什么,那一行代码都是相当多的。
#define addint(S, n) do { \
unsigned char c = pow(2, (CHAR_SIZE -1) - (n % CHAR_SIZE)); \
(*S)[n/CHAR_SIZE] |= c \
} while(0)