swift - إنشاء كائن خطوة واحدة وتهيئة الخاصية في سويفت؟




properties swift2 (4)

السبب أنا أبحث عن هذا هو حتى أتمكن من إضافة مجموعة من الحالات إلى صفيف دون صراحة خلق المتغيرات لكل طالب المثال [.]

أنا لست على دراية C #، ولكن في سويفت، يمكنك القيام بذلك فقط من خلال تهيئة الكائنات داخل إعلان صفيف:

var list: [Student] = [
    Student(firstName: "John", lastName: "Doe"),
    Student(firstName: "Jane", lastName: "Jones"),
    Student(firstName: "Jason", lastName: "Smith")
]

المقاربات الأخرى المقترحة هي كلها صالحة على قدم المساواة، ولكن إذا كنت تحاول ببساطة لملء صفيف دون إعلان أي متغيرات، سويفت يجعل من السهل.

هل هناك طريقة لتعيين قيم الخاصية لمثيل فئة حتى لو لم تكن معلمة في منشئ إينيت؟ على سبيل المثال، في C # يمكنني القيام بذلك:

public class Student
{
   public string firstName;
   public string lastName;
}

var student1 = new Student();
var student2 = new Student { firstName = "John", lastName  = "Doe" };

إشعار student2 لا يزال بإمكاني تعيين القيم أثناء التهيئة على الرغم من عدم وجود منشئ في الصف.

لم أتمكن من العثور في الوثائق إذا كنت تستطيع أن تفعل شيئا من هذا القبيل ل سويفت. إذا لم يكن كذلك، فهل هناك طريقة لاستخدام extensions لتمديد فئة " Student لتعيين قيم الخاصية أثناء التهيئة؟

السبب أنا أبحث عن هذا هو حتى أتمكن من إضافة مجموعة من مثيلات إلى صفيف دون صراحة خلق المتغيرات لكل طالب المثال، مثل هذا:

var list = new[] {
  new Student { firstName = "John", lastName  = "Doe" },
  new Student { firstName = "Jane", lastName  = "Jones" },
  new Student { firstName = "Jason", lastName  = "Smith" }
}

أي وسيلة الأصلي أو أنيقة لتحقيق ذلك في سويفت؟


أردت فقط أن أشير إلى أنه إذا كان هيكل الخاص بك يمكن أن تكون غير قابلة للتغيير، يمكنك فقط استخدام struct بدلا من class وستحصل على التهيئة الضمنية مجانا:

مجرد لصق هذا في ملعب وتغيير الهيكل إلى فئة وسترى ما أعنيه.

struct Student
{
    var firstName : String?
    var lastName : String?
}

var student = Student(firstName: "Dan", lastName: "Beaulieu")

لديك بضعة خيارات بناء على الطريقة التي تريد بها تكوين هذا النوع وما هي البنية الأكثر ملائمة لك.

يمكنك تعريف إنيتيزر مريحة التي تقبل الخصائص التي تريد تعيينها. من المفيد إذا كنت تقوم بتعيين نفس الخصائص طوال الوقت، وأقل فائدة إذا كنت تقوم بتعيين مجموعة غير متناسقة من الخصائص الاختيارية.

public class Student
{
    public var firstName:String?;
    public var lastName:String?;
}

extension Student {
    convenience init(firstName: String, lastName: String) {
        self.init()
        self.firstName = firstName
        self.lastName = lastName
    }
}

Student(firstName: "Any", lastName: "Body")

هل يمكن تحديد المتلقي المناسب الذي يقبل كتلة لتكوين المثيل الجديد.

extension Student {
    convenience init(_ configure: (Student) -> Void ) {
        self.init()
        configure(self)
    }
}

Student( { $0.firstName = "Any"; $0.lastName = "Body" } )

هل يمكن أن تقليد طريقة tap روبي كما ملحق حتى تتمكن من العمل على كائن في منتصف سلسلة الطريقة.

extension Student {
    func tap(block: (Student) -> Void) -> Self {
        block(self)
        return self
    }
}

Student().tap({ $0.firstName = "Any"; $0.lastName = "body"})

إذا كان آخر واحد مفيد قد ترغب في أن تكون قادرة على اعتماد tap على أي كائن. لا أعتقد أنك تستطيع أن تفعل ذلك تلقائيا ولكن يمكنك تحديد التنفيذ الافتراضي لجعله أسهل:

protocol Tap: AnyObject {}

extension Tap {
    func tap(block: (Self) -> Void) -> Self {
        block(self)
        return self
    }
}

extension Student: Tap {}

Student().tap({ $0.firstName = "Any"; $0.lastName = "body"})

هذا هو مجرد الحلوى النحوية ولكن يمكنني استخدام مشغل مخصص للقيام بهذا النوع من الشيء:

 infix operator <- { associativity right precedence 90 }
 func <-<T:AnyObject>(var left:T, right:(T)->()) -> T
 {
   right(left)
   return left
 }

 let rgbButtons:[UIButton] = 
   [ 
     UIButton() <- { $0.backgroundColor = UIColor.redColor() },
     UIButton() <- { $0.backgroundColor = UIColor.greenColor() },
     UIButton() <- { $0.backgroundColor = UIColor.blueColor() }
   ]




instance