class - 使用自动生成的公共(public)属性方法与创建访问私有(private)属性的方法

标签 class oop attributes raku

假设我有一个具有多个属性的类,但我只需要其中一些来构建对象;其余属性的值取决于这些公共(public)属性。但是,我仍然想使用以属性命名的方法来访问其余属性的值。从我的脑海中,有两个选择:

第一个选项:

  • 重载new方法。或留下new方法,而是使用 BUILD子方法将传递的参数设置为正确的属性并使用此参数的值设置剩余的属性。
  • class Foo {
        has Int $.a;
        has Int $.b;
        has Int $.c;
    
        submethod BUILD(:$!a) {
            $!b = $!a ** 2;
            $!c = $!a ** 3;
        }
    }
    
    say Foo.new(:2a, :1b);   #=> Foo.new(a => 2, b => 4, c => 8)
    say Foo.new(:2a, :1b).b; #=> 8
    

    第二种选择:

    $. 声明仅对象构造所需的那些属性,并使用 $! 修改剩余的属性(用 TWEAK 声明)对象构造后的子方法。但是,现在我需要为这些属性创建访问器方法。
    class Bar {
        has Int $.a;
        has Int $!b;
        has Int $!c;
    
        submethod TWEAK {
            $!b = $!a ** 2;
            $!c = $!a ** 3;
        }
    
        method b { $!b }
        method c { $!c }
    }
    
    say Bar.new(:2a, :1b);   #=> Bar.new(a => 2)
    say Bar.new(:2a, :1b).b; #=> 8
    

    问题

    最好的选择是什么?还有其他选择吗?每个选项的优点/缺点是什么?

    最佳答案

    就我个人而言,我会很简单:

    class Foo { 
        has Int $.a; 
        has Int $!b = $!a ** 2; 
        has Int $!c = $!a ** 3;
        method b { $!b }
        method c { $!c }
    }
    say Foo.new(:2a, :1b); #=>  Foo.new(a => 2)
    say Foo.new(:2a, :1b).b; #=> 4
    

    只需使用属性的默认构造函数和默认值,并添加几个基本的读取方法。默认构造函数只更新公共(public)属性,所以如果你尝试覆盖 bc这被忽略了。

    如果您愿意,可以添加 BUILD如果有人尝试并设置它们,子方法会出错。

    在这个案例(可能是最终用例)的评论中提出了一个很好的观点:
    class Foo { 
        has Int $.a; 
        method b() is pure { $!a ** 2 }
        method c() is pure { $!a ** 3 }
    }
    say Foo.new(:2a, :1b); #=>  Foo.new(a => 2)
    say Foo.new(:2a, :1b).b; #=> 4
    

    根据计算的复杂性,您可能希望使用 is cached特质也。

    关于class - 使用自动生成的公共(public)属性方法与创建访问私有(private)属性的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59568073/

    相关文章:

    Java 骰子游戏生成新数字时遇到问题

    javascript - 为什么在 JavaScript 中使用 new 和构造函数是错误的

    javascript - 选择的设置属性不持久

    sockets - 有人可以解释一下 "from socket import example"和 "import socket"之间的区别吗?

    php - 如何在 PHP 中使用多个类

    c# - 动态调用方法和类名

    ios - Swift:将 CGSize 应用于 Button 类不改变

    oop - 每个返回 `this` 的方法都是单子(monad)吗?

    java - 如何处理其他打开的 Jframe

    c# - System.Runtime.InteropServices.GuidAttribute 是否用于除 COM 互操作之外的任何内容