【问题标题】:objective-c: return value目标-c:返回值
【发布时间】:2011-02-15 10:00:09
【问题描述】:

我正在阅读 Stephen Kochan 的“Objective-C 编程”(我是 n0000b)。在练习 4-8 之前,一切对我来说都是显而易见的。

它要求我修改本章前面创建的“累加器”类中的方法,以便在使用其中一种数学方法(基本上它是一个计算器)时“返回”累加器的值。我最初认为这意味着我希望程序在使用其中一种方法时显示结果(+、-、*、/),所以我将其设置为这样做,所以每一行都显示累积结果而不是只是最终结果:

[deskCalc setAccumulator: 0.0];
[deskCalc add: 200.]; //the result is displayed
[deskCalc divide: 100.0]; //the result is displayed
[deskCalc subtract: 1.0]; //the result is displayed
[deskCalc multiply: 5]; //the result is displayed
NSLog (@"The result is %g", [deskCalc accumulator]);

但是在查找了其他人的解决方案之后,似乎“返回累加器的值”意味着不同的东西。

有人可以向我描述返回值的含义以及它的用途吗?我已经看过前一章几次,但我仍然不清楚这将如何使程序的行为有所不同。

谢谢! -安德鲁

【问题讨论】:

    标签: objective-c return-value


    【解决方案1】:

    您的累加器类中的计算方法目前可能看起来像这样:

    - (void)add:(float)aFloat {
        result += aFloat;
        NSLog(@"%f", result);
    }
    

    此方法在其当前状态下不返回任何内容(void)。它仅在屏幕上输出当前总数。这对练习来说很好,但在现实世界的程序中,如果计算结果显示在屏幕上,它可能不会很有用。相反,您可能希望对结果执行其他操作,因此您希望方法返回它。例如,NSString 类有一个方法length。如果要在屏幕上打印字符串的长度,此方法将不是很有用。相反,它返回长度,所以程序可以用这个值做一些有用的事情(比如检查字符串的长度是否正确):

    int length = [tweet length];
    if (length > 140) {
        // display a useful error message
        ...
    } else {
        // tweet it :)
        ...
    }
    

    要修改您的计算器方法以返回某些内容,您将 (a) 必须更改方法签名以具有返回值,并且 (b) 实际返回此值。

    在方法签名中,只需将返回类型更改为 void 以外的类型。在您的示例中,正确的类型可能是浮点数(或计算器内部用于其当前结果的任何类型)。

    - (float)add:(float)aFloat {
        ...
    }
    

    要真正返回当前值,您可以添加一个return 语句,添加方法的结尾(在结束} 之前)

    return result;
    

    (这里假设result是包含当前计算结果的实例变量)。

    【讨论】:

    • 谢谢,这很有用。然而,我仍然对我的“累加器”值如何“记住”我的程序中以前的值感到困惑,即使我没有在每个数学方法中添加“返回累加器”。例如,它从 0 开始,然后我“加 200”,然后“减 5”,然后如果我打印结果,它会告诉我“195”。如果我不是每次都将值返回到“累加器”,它如何跟踪?
    • 在我的示例中,我假设结果是在计算器的类接口中声明的实例变量float result;。此实例变量在计算器实例的整个生命周期中都存在,因此每次使用它执行操作时,它都会根据其先前的值进行更改,并且 - 通过建议的修改 - 操作后的当前值也由方法返回.
    • 这个例子当然是相当做作的。在普通程序中,您更有可能拥有影响对象内部状态的方法(例如,将添加 x 添加到内部结果)不返回任何内容(或者可能返回错误代码以指示操作成功/失败),然后是另一种获取计算器当前状态(当前结果)的方法。或者根本不影响对象内部状态但对其参数执行某些操作然后返回某种结果的方法。
    • 我上一条评论的示例:[name appendString:@" , Ph.D."] 影响可变字符串对象的内部状态(如果 name 之前是“John Doe”,那么之后将是“John Doe, Ph.D.”)但不返回任何东西。另一方面,[name stringByAppendingString:@" , Ph.D."] 不会更改 name 字符串对象(它仍然是“John Doe”),而是返回一个包含“John Doe, Ph.D.”的新字符串对象。
    【解决方案2】:

    他们要求您修改您的加法、除法、减法方法,以便在执行的操作完成后返回累加器的值。我的猜测是您最初的 add/divide/etc 方法定义了一个(void)返回值,这意味着它们不会从函数调用中返回任何值。因此,您无法执行类似于以下的执行:

    NSLog(@"Updated value: %g", [deskCalc substract: 1.0]);
    

    从函数返回值意味着该函数不仅可以执行某种类型的操作,而且还可以将某种值返回给调用代码。返回值的目的是它允许您将代码分成逻辑组件,允许代码重用并提高代码的可维护性。

    这是一个有用的示例:假设您需要计算一个数字的平方根。您的代码不关心如何计算平方根,您只需要这个数字。通过使用一个函数,该函数接受一个值,计算其平方根,然后将计算出的值返回给调用代码,您的代码可以担心它需要对函数的返回值做什么,而不必担心逻辑本身.

    这是一个返回 NSString 的函数示例:

    - (NSString *) getAString {
        return @"String being returned";
    }
    

    以下是您将如何使用该功能:

    NSString *myString = [someObject getAString];
    

    我希望这对您的学习过程有所帮助。

    【讨论】:

    • 感谢您的回复!我确实了解了基本概念,但仍然对功能感到困惑(不幸的是,您的示例使用了书中尚未涵盖的语法......)。例如,最初(没有在每个方法中添加“return accumulator;”,“accumulator”仍然存储每次对其执行操作时的回复。“add 20”将原始值加 20,然后在下一行“减法” 5" 将从累计总数中减去 5。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2012-01-07
    • 1970-01-01
    • 2021-05-05
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多