我总是对我的评论不满意,我只是想看看这些评论是否可以接受,或者我应该在什么地方包括/应该在哪里包括它们。

评论

如果我曾经是编程老师,请提醒我不要在乎代码注释!

#1 楼

欢迎来到地狱评论,和个人品味。您可能对的核心问题有多种答案:

您没有发表足够的评论。
您评论了所有错误的内容。 br />您的注释格式错误。
您缺少正式注释。 ,除非您能告诉我们为什么您被标记为...... ;-)

关于一般注释
好,注释应该使代码没有告诉我们的内容变得清楚。
我再说一遍。

应该使注释清楚代码没有告诉我们的内容。还是不,是另外一个故事。我发现在学术上对注释使用标记常常与注释的使用背道而驰……尤其是当代码是好的代码时。

好的代码很少需要注释。

因此,请遵循此逻辑,然后遵循相反的顺序...

注释使内容清楚代码还没有告诉我们。
好的代码很少需要注释。

因此....

好的代码很少需要注释。
好的代码必须清楚地说明代码的功能,而无需其他说明。 />
import java.util.*; //so I can use scanner


现在,如果您的代码是:
import java.util.Scanner;

则不需要注释。
您的下一条注释在这里: br />
  int max = 100; //sets limit on the random number generator


好吧,实际上,这不是可怕的注释或代码。但是,如果我们给它取一个体面的名称,那就更好了:
int randomGeneratorLimit = 100;

如果将那个魔术数字设为常数,那就更好了:根本不需要发表评论。
下一行,这行:

private static final int RANDOM_GENERATOR_LIMIT = 100;


好吧,这很有趣。...由于您正在使用循环,因此实际上需要在此处添加注释。
如果将其转换为do-while循环,并使用一些函数提取...那么您可以将您的代码转换为自记录的,无注释的块:
  while (play) { //so game will restart after a win

,则可以按如下方式使用该函数: 。
类似地,您也具有以下代码: br />再次,这使逻辑清晰,不需要注释。
我相信现在已经消除了所有注释。代码是不言自明的。
在其他新闻中,如果您有更多具有好名字的函数,那么您的代码也将更易于阅读。代码应填补您的代码没有的空白。另外,您的注释应提供动机的详细信息,而不是代码的应用。通常,您应该只评论代码为什么会执行操作,而不是代码正在做什么。
这会导致您缺少其他评论... JavaDoc。
JavaDoc是应该在抽象级别上解释代码的功能。
您没有JavaDoc,您应该这样做。 JavaDoc是您描述代码功能的地方,因为通常,阅读Javadoc的人不会阅读代码,因此他们需要其他东西来告诉他们代码的功能。

评论


\ $ \ begingroup \ $
关于评论的绝佳答案!从现在开始,这将是我最喜欢的参考,以链接答案。
\ $ \ endgroup \ $
– Heslacher
15年5月8日在4:42

\ $ \ begingroup \ $
很好。记录“为什么”而不是“如何”,代码应使“如何”尽可能明显。
\ $ \ endgroup \ $
–乍得·舍金斯(Chad Schouggins)
15年5月14日在20:06



\ $ \ begingroup \ $
很棒的答案。我喜欢使用OP的原始示例,为每个评论提出一个如何摆脱它的完美示例。关于JavaDoc也很不错。问问自己,您通过Javadoc使用了多少个库,以及实际上通过阅读源使用了多少个...曾经读过Object.toString的源代码吗?而且,如果您的代码没有JavaDocs,那么对于那些不阅读它们使用的所有库的所有源代码的具有相似品味的人来说,它的可用性如何?
\ $ \ endgroup \ $
– Stijn de Witt
2015年12月8日23:14在

\ $ \ begingroup \ $
完全是OT,但是System.out.print(“是否要再次播放?”);立即让我想到了WarGames。现在,我们将返回到您定期进行的代码审查...
\ $ \ endgroup \ $
– FreeMan
17 Mar 17 '17 at 17:05

\ $ \ begingroup \ $
非常好。大多数人建议编写更好的注释,但是您建议编写更好的代码,以使注释过时。
\ $ \ endgroup \ $
– yuri
18年3月1日在12:21

#2 楼

所以你想写出好的评论。
好的评论...

...说为什么,而不是什么。代码已经在说了。
...如果代码更改,请不要撒谎。


让我们看看...
import java.util.*; //so I can use scanner

问题是您要导入整个库,并指定仅针对其中一种类型的库执行此操作。要么是您在撒谎,然后实际上是在使用更多代码,要么import语句过于杀伤。
int max = 100; //sets limit on the random number generator

对变量的注释通常表示命名不佳,因为好的标识符是不言而喻的。如果将max称为maxRandomValue,是否需要此注释?
int guess;//so I can compare console input to random number

这是另一条注释,代替了更有意义的标识符。如果guess被称为userInput,是否需要此注释?
while (play) { //so game will restart after a win

也没有理由发表此注释;很清楚这里的意图是什么。我在while (play)上看到的唯一潜在问题是play是一个动词,当布尔标识符以ishas开头时,布尔标识符更清晰-在这种情况下为while(isPlaying)
 //so user can continue guessing until correct
 boolean win = false;

此评论为'也需要。再次很清楚是什么意思,但是再一次,它看起来像一个动词,可以称为isCorrectGuess

这是一个有趣的东西:
//so user can choose to play another game    

    String answer = input.nextLine();
    char firstLetter = answer.charAt(0);
    if (firstLetter == 'y' || firstLetter == 'Y') {
    play = true;  
    } else {
    play = false;
} 

缩进是显然不在这里,这令人困惑。考虑:
    String answer = input.nextLine();
    char firstLetter = answer.charAt(0);
    if (firstLetter == 'y' || firstLetter == 'Y') {
        play = true;  
    } else {
        play = false;
    } 

,但是您使用条件在一个分支中分配true,在另一个分支中分配false-因此,整个if块是无用的:关于注释...
    String answer = input.nextLine();
    char firstLetter = answer.charAt(0);
    play = firstLetter == 'y' || firstLetter == 'Y';

编写该表达式的方式使其看起来像是在说为什么,但它基本上说的是“这段代码确实可以实现[...]”。每当发生这种情况时,经验法则就是您应该将该块提取到其自己的方法中。

最重要的是,我认为这些注释都不是真正需要的。并帮自己一个忙,删除“以便abc可以xyz”的提法。

评论


\ $ \ begingroup \ $
我认为play是比isPlay更好的变量名称。 isPlaying适用于布尔型getter方法。对于布尔变量名称IMO,成为动词不是问题。 (我认为Java约定在这一方面与我一致)
\ $ \ endgroup \ $
–西蒙·福斯伯格
2015年5月9日,0:02

#3 楼

错误

System.out.print("Your guess? " + numberToGuess);

好吧,我想我想第一次都猜对了,每次...:(<< />

@rolfl和@Mat的马克杯对您的评论问题提供了宝贵的见解,因此,我将尝试解决其中的代码部分...

使用boolean标志

当前,两个循环条件都取决于设置boolean标志,这确实使代码更易于阅读;或者,由于只有两个特定条件要从两个循环中退出,因此您可以也可以考虑在以下位置执行break



猜测正确的数字

if (guess == numberToGuess) {
    break;
}



退出在游戏中

if ( <first character of input is y/Y> ) {
    break;
}



此后,您的while -loops就是while (true) { ... }。我会在上面推荐它。

验证用户输入

guess = input.nextInt();
...
input.nextLine();


如果非输入了-integer输入,不仅要记住必须通过在末尾执行nextInt()来“消耗”当前行。我建议读入整行,执行InputMismatchException并捕获nextLine()的无效输入。然后,您可以反复提示用户,直到获得一个有效的整数(也许您要排除负值或超出指定猜测范围的数字)。

打印此或那个

在两个地方,您正在做与以下操作类似的事情:假设Integer.parseInt(line)仅具有一个占位符NumberFormatException,并且format不需要在结尾添加换行符,因为该方法正在添加它。用法:

if (condition) {
    System.out.println("..." + "x" + "...");
} else {
    System.out.println("..." + "y" + "...");
}


是否要再次玩?

比较可以简化为:

private static void printEither(boolean condition, String format, 
                                    String ifTrue, String ifFalse) {
    System.out.printf(format + "%n", condition ? ifTrue : ifFalse);
}


"%s"

如果您在format上使用Java 7,也应该使用try-with-resources

评论


\ $ \ begingroup \ $
我不喜欢line input.nextLine()。substring(0,1).equalsIgnoreCase(“ y”),太多的链接调用。此外,如果将写入空行,则会引发异常。我会提取“您想再玩一次”的逻辑。用另一种方法。
\ $ \ endgroup \ $
–user131519
17年5月29日在9:40

#4 楼

奇怪的是,您的介绍性文字说:"Can you guess the word?"我以为这是一种猜数字游戏,而不是子手。最差的一个是//so I can use scanner,这有点误导,因为您还需要import作为java.util.Random。您最好不要编写
import java.util.Random;
import java.util.Scanner;


…在那儿没有评论。线。纯粹的代码长度使得难以一次查看和理解所有代码。通过将其分解为功能,可以分别分析每个功能,还可以为每个功能块命名。如果您选择好名字,那么该程序可能会有些自我记录。如果您编写JavaDoc,那将是更有效的注释类型。

此外,您应避免依赖main()play等标志变量来控制程序流。正确编写循环,并在必要时使用诸如wincontinue之类的关键字到达您要去的地方。问题,您的程序将以break崩溃。

import java.util.Random;
import java.util.Scanner;

public class GuessingGame {
    private static final int MAX = 100;
    private final Random rand = new Random();
    private final Scanner input;

    public GuessingGame(Scanner input) {
        this.input = input;
    }

    /**
     * Picks a number and asks for guesses until a correct guess.
     *
     * @return The number of guesses used (1 if guessed on the first try)
     */
    public int play() {
        System.out.println("I'm thinking of a number between 1 and " + MAX + "...");
        int numberToGuess = rand.nextInt(MAX) + 1;
        int score;
        for (score = 1; ; score++) {
            System.out.print("Your guess? ");
            int guess = input.nextInt();

            if (guess == numberToGuess) {
               break;
            } else if (guess > numberToGuess) {
               System.out.println("It's lower.");
            } else if (guess < numberToGuess) {
               System.out.println("It's higher.");
            }      
            input.nextLine();
        }
        System.out.printf("You got it right in %d guess%s!\n",
                          score,
                          score == 1 ? "" : "es");
        return score;
    }

    /**
     * Asks the user if he/she wants to play again.
     *
     * @return true for a "yes" answer, false for a "no" or unrecognized answer
     */
    public boolean playAgain() {
        System.out.print("Do you want to play again? ");
        String answer;
        while ((answer = input.nextLine()).isEmpty());
        char firstLetter = answer.charAt(0);
        return (firstLetter == 'y' || firstLetter == 'Y');
    }

    /**
     * Plays number-guessing games until user decides to quit,
     * then displays statistics.
     */
    public static void main(String[] args) {
        try (Scanner input = new Scanner(System.in)) {
            System.out.println("Can you guess the number?\n" +
                               "I am sure you cannot guess!\n" +
                               "Go ahead and try!\n");

            int guesses = 0, gamesPlayed = 0, bestScore = Integer.MAX_VALUE;
            GuessingGame game = new GuessingGame(input);
            do {
                int score = game.play();
                bestScore = Math.min(bestScore, score);
                guesses += score;
                gamesPlayed++;
            } while (game.playAgain());

            System.out.println("Overall results:");
            System.out.printf("Total games   = %d\n", gamesPlayed);  
            System.out.printf("Total guesses = %d\n", guesses);
            System.out.printf("Guesses/game  = %.1f\n", guesses/(double)gamesPlayed);
            System.out.printf("Best game     = %d\n", bestScore);
        }
    }
}


#5 楼

您的代码缺少几个非常重要的注释。您确实有一些评论是谎言,有些是微不足道的,但有些则没有说出您应该说的话。
所有人中最重要的评论
(从律师的角度)
/>
// Copyright 2015 Eric Irwin. All rights reserved.

在课堂作业中这无关紧要。在工作世界中,这可能很重要。有些人阐述了保留哪些权利。为什么?保留所有权利。或者可以参考许可协议。保持简短和简单,可以轻松插入此非常重要的注释。
所有最重要的注释
(从javadoc的角度来看)
每个类,每个函数都应有一个javadoc注释。您不要(您不应该!)落伍。不要说什么时候写的,甚至是谁写的。用通俗的英语(或通俗的法语,德语或其他方式)写出为什么存在类或函数。
对于类,请说出为什么存在该类,以及如何使用它。大多数类具有多个成员函数和多个数据成员。随机调用这些成员函数的外部用户很可能是敬酒的。成员函数需要如何排序,它们如何彼此交互:这就是您要放入该类javadoc注释中的内容。
对于函数,请记录该函数的作用,为什么存在-用简单的英语。记录函数的参数和函数的返回值。在一种情况下(main),这可能很明显,但是一个程序只有一个mainmain的参数通常很棘手。在这种情况下,您不需要使用参数-可以这么说!一个完美的例子:
while (play) { //so game will restart after a win

我认为更好:
// Play game after game until the user decides to stop.
while (play) {

该外部循环存在,因此用户可以玩多个游戏。 (这可能是任务的一部分。这么说。)这就是全局。那么游戏胜利后会重启吗?那不是“大局”。尽管编写良好的代码可以在一定程度上解释自己,但不能解释全局,aka意图或体系结构。在线评论。这种评论风格迫使人们变得简洁。往往过于简洁。它还鼓励人们评论显而易见的内容(例如i++; // increment i)。比i++; // increment i更糟糕的是,注释与代码不一致。不需要对显而易见的东西发表评论。评论不是那么明显吗?行尾注释通常效果不佳。

评论


\ $ \ begingroup \ $
我对评论的看法是不典型的。我写的软件做得不正确,可能会杀死人或冒数亿美元的风险。评论很重要。他们需要说出事物存在的原因,为什么选择特定的路径,事物的作用(但要从整体上看)。他们也不能异想天开。得益于那些属于超人类物种的奇妙生物,这些软件被杀害的可能性不大。
\ $ \ endgroup \ $
–David Hammen
2015年5月10日4:20



\ $ \ begingroup \ $
记录在案,保留所有权利。在评论中发布,然后发布到Code Review将适得其反,因为当您在此处发布时,它会根据CC-BY-SA许可证自动发布。
\ $ \ endgroup \ $
–西蒙·福斯伯格
15年5月12日在22:19

\ $ \ begingroup \ $
“如您所见,陪审团在被告的源代码中写了'//可能爆炸'。您当时认为到底是怎么回事。”
\ $ \ endgroup \ $
–LegendLength
17年7月15日在20:08