2017-02-09 65 views
0

我有2個類:一個具有2個屬性,另一個具有數組。我想創建一個第一類對象的數組。精靈中的對象數組

該示例編譯,但給出了錯誤的答案。爲什麼?


[indent=4] 

class data 

    prop first_name : string = " " 
    prop last_name : string = " " 

class Arr : Object 

    person : data 
    dataset : array of data[] 

    init 
     person = new data() 
     dataset = new array of data[3] 

    def date_input() 

     print "\n data input \n" 

     person.first_name = "Egon" 
     person.last_name = "Meier" 

     dataset[0] = person 

     print dataset[0].first_name + " " + dataset[0].last_name 

     person.first_name = "John" 
     person.last_name = "Schneider" 

     dataset[1] = person 

     print dataset[1].first_name + " " + dataset[1].last_name 

     person.first_name = "Erwin" 
     person.last_name = "Müller" 

     dataset[2] = person 

     print dataset[2].first_name + " " + dataset[2].last_name 


    def date_output() 

     print "\n data output \n" 

     for i : int = 0 to 2 
      print dataset[i].first_name + " " + dataset[i].last_name 

init 

    Intl.setlocale() 

    var a = new Arr() 

    a.date_input() 
    a.date_output() 

回答

1

最根本的問題是你指的是同一個人三次,但每次改變他們的名字。在精靈中有價值類型和參考類型。值類型更簡單,並在分配時自動複製。例如:

[indent=4] 
init 
    a:int = 2 
    b:int = a 
    b = 3 
    print("a is still %i", a) 

引用類型具有可以容易被複制的優點,精靈簡單地保持取得的引用的計數。所以,要複製引用類型的引用計數增加一個,但是這也意味着改變底層對象將影響引用它的所有變量:

[indent=4] 
init 
    a:ReferenceTypeExample = new ReferenceTypeExample() 
    a.field = 2 
    b:ReferenceTypeExample = a 
    b.field = 3 
    print("a.field is not 2, but %i", a.field) 

class ReferenceTypeExample 
    field:int = 0 

在工作下面的例子我已經Person

[indent=4] 
init 
    Intl.setlocale() 

    var group = new Group() 
    print "\n data input \n" 
    try 
     group.add_person(new Person("Egon", "Meier")) 
     group.add_person(new Person("John", "Schneider")) 
     group.add_person(new Person("Erwin", "Müller")) 
    except err:GroupError 
     print(err.message) 
    print(@"$group") 


class Person 
    prop readonly first_name:string = "" 
    prop readonly last_name:string = "" 

    construct(first:string, last:string) 
     _first_name = first 
     _last_name = last 


exception GroupError 
    GROUP_FULL 

class Group 
    _people_count:int = -1 
    _group:new array of Person 
    _max_size:int = 2 

    construct() 
     _group = new array of Person[ _max_size ] 

    def add_person(person:Person) raises GroupError 
     _people_count ++ 
     if _people_count > _max_size 
      _people_count = _max_size 
      raise new GroupError.GROUP_FULL(
         "Group is full. Maximum is %i members", 
         _max_size + 1 
         ) 
     _group[ _people_count ] = person 

     print(" " + _group[ _people_count ].first_name + 
       " " + _group[ _people_count ].last_name 
      ) 

    def to_string():string 
     result:string = "\n data output \n\n" 
     if _people_count < 0 
      result += " empty group" 
      return result 
     for i:int = 0 to _people_count 
      result += " " + _group[i].first_name + \ 
         " " + _group[i].last_name + "\n" 
     return result 

關於代碼的一些細節:通過使用readonly屬性對象

  • 通過改變屬性是readonly如果編譯程序時嘗試更改Person的詳細信息,則會出現錯誤。在您的示例中,如果將data的屬性更改爲readonly,則Vala編譯器會警告您嘗試重寫當前對象
  • Person將其數據值設置在構造函數中,然後嘗試更改他們是一個錯誤
  • 對於一個簡單的屬性精靈生成一個自動後臺字段,以下劃線開頭。例如,在Person財產first_name有支持字段_first_name,這是該領域是在構造函數中設置包括方法本身的人的名字
  • 相反,一種稱爲add_person()使用,需要一個Person作爲參數。這將抽象類的具體數據分開
  • 檢查已添加到add_person()方法以確保數組不超出其限制。如果將更多人添加到組中,則會發生異常
  • init塊中的add_person()調用將創建Person作爲方法調用的一部分。這意味着Person對象的引用不保存在init塊中
+0

感謝您的答案的優質! – txasatonga

+0

感謝您的幫助。 – user7450201