【问题标题】:How would one rewrite a program to eliminate side effects?如何重写程序以消除副作用?
【发布时间】:2018-05-26 12:31:45
【问题描述】:

我正在尝试在 Java 教科书中研究这个问题。 问题是重写这个程序以消除副作用, 通过调用函数(或方法,这有点像)会产生对对象或程序变量状态的更改。

包装副作用;

public class SideEffect {

    **public static int x;**

    public static int f(int n){
        x = x * 2;
        return x + n;
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        x = 5;

        //int result = f(x) + f(x);
        int result = 2 * f(x);
        //System.out.println(result);
    }

}

注释掉的行是当我实现整数变量并将其打印输出时发生的情况。 如果我实现这些行并注释掉其他行, 结果是 45。 如果实施另一个, 结果是 30。 有没有办法理顺程序,所以没有副作用? 我在想我删除了全局变量行,因为它在书中说它会导致这种糟糕的情况, 混乱的代码。 但是我还能尝试什么?

【问题讨论】:

  • 你想要的输出是什么?
  • 问题没有说明具体的输出。它只是建议让函数接受 x 的值作为参数使用,而不是修改全局变量。
  • “消除副作用”,我猜你的意思是外部可见副作用由方法执行产生。还有其他类型的副作用,在 Java 中你不能轻易避免。
  • 摆脱全局变量是正确的。如果你不知道它的输出应该是什么,就很难修复一个程序,所以很难说f函数的实现应该是什么。
  • 程序的全部目的是产生副作用。如果你的程序没有副作用,比如 print 语句,你可以用一个完全空的程序替换它。

标签: java lambda functional-programming


【解决方案1】:

好的,好多了:

包装副作用;

public class SideEffect {

      public static int f(int x, int n){
        x = x * 2;
        return x + n;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       int x = 5;
       int result = f(x , 5) + f(x, 5);
        System.out.println(result);

    }
}

我已将 x 作为 int 引入公共静态 int,因此我不必初始化变量。

【讨论】:

    【解决方案2】:

    这可能有效,但我不确定。我已经注释了全局变量,然后在 f 方法和 main 方法中声明了 int x 。结果是无论我是否使用“int result”调用都没有关系,它仍然是 10 作为输出。但我可能错了:

    public class SideEffect {
    
        **//public static int x;**
    
        public static int f(int n){
            int x = 0;
            x = x * 2;
            return x + n;
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            int x = 5;
    
            //int result = f(x) + f(x);
            int result = 2 * f(x);
            System.out.println(result);
            //System.out.println(result2);
        }
    
    }
    

    【讨论】:

    • 你可以重写为:public static int f(int n){ return n;} 可能不是你想要的。
    【解决方案3】:

    我知道这是一项任务,但这样的事情总是有些令人抓狂。 “问题”是他们以一种永远不应该使用的方式使用全局变量。 “医生,我这样做会很痛。不要那样做”。

    通常静态(类级别)变量很少是您真正想要的。 main() 还用于实例化您的对象并使它们在世界上消失,而不是像 C 程序那样做繁重的工作。

    创建类并按值传递。不要使用全局变量,除非你真的想拥有一个且只有一个实例。

    这真的是我能提供的最好的,因为从你的问题中不清楚什么是“正确”的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-03
      • 1970-01-01
      • 2020-03-01
      • 2017-08-09
      • 1970-01-01
      • 2022-01-06
      • 2022-08-24
      • 1970-01-01
      相关资源
      最近更新 更多