সুইফটে গণনাযোগ্য পঠনযোগ্য কেবলমাত্র বনাম ফাংশন


98

সুইফট ডাব্লুডাব্লুডিসি সেশনের পরিচিতিতে, কেবল পঠনযোগ্য সম্পত্তি descriptionপ্রদর্শিত হয়:

class Vehicle {
    var numberOfWheels = 0
    var description: String {
        return "\(numberOfWheels) wheels"
    }
}

let vehicle = Vehicle()
println(vehicle.description)

পরিবর্তে কোনও পদ্ধতি ব্যবহারের মাধ্যমে উপরোক্ত পদ্ধতির চয়ন করার ক্ষেত্রে কী কোনও প্রভাব রয়েছে:

class Vehicle {
    var numberOfWheels = 0
    func description() -> String {
        return "\(numberOfWheels) wheels"
    }
}

let vehicle = Vehicle()
println(vehicle.description())

আমার কাছে মনে হয় আপনি কেবলমাত্র পঠনযোগ্য গণনা করা সম্পত্তি বেছে নেওয়ার সবচেয়ে সুস্পষ্ট কারণগুলি হ'ল:

  • শব্দার্থবিজ্ঞান - এই উদাহরণে এটি descriptionক্লাসের সম্পত্তি হিসাবে বিবেচনা করে, বরং এটি সম্পাদন করে এমন কোনও ক্রিয়াকলাপ।
  • ব্রেভিটি / স্পষ্টতা - মান পাওয়ার সময় খালি বন্ধনী ব্যবহারের প্রয়োজনকে বাধা দেয়।

স্পষ্টত উপরের উদাহরণটি অত্যধিক সরল, তবে একে অপরের থেকে একটি বেছে নেওয়ার অন্যান্য কি ভাল কারণ আছে? উদাহরণস্বরূপ, ফাংশন বা বৈশিষ্ট্যগুলির কিছু বৈশিষ্ট্য রয়েছে যা আপনার কোনটি ব্যবহারের সিদ্ধান্তকে পরিচালিত করবে?


এনবি প্রথম নজরে এটি বেশ একটি সাধারণ ওওপি প্রশ্নের মতো মনে হয় তবে আমি এই ভাষাটি ব্যবহার করার সময় যে কোনও সুইফট-নির্দিষ্ট বৈশিষ্ট্য যা সেরা অনুশীলনকে গাইড করতে পারে তা জানতে আগ্রহী।


4
204 অধিবেশন দেখুন - "যখন প্রপার্টি ব্যবহার করবেন না" এর কিছু টিপস রয়েছে
কোস্টিয়ান্টিন কোভাল

4
অপেক্ষা করুন, আপনি কেবল পঠনযোগ্য সম্পত্তি করতে পারেন এবং এড়িয়ে যেতে পারেন get {}? আমি জানতাম না, ধন্যবাদ!
ড্যান রোজনস্টার্ক

ডাব্লুডব্লিউডিসি 14 অধিবেশন 204 এখানে (ভিডিও এবং স্লাইড), বিকাশকারী.অ্যাপল.
com

উত্তর:


54

এটি আমার কাছে মনে হয় এটি বেশিরভাগ শৈলীর বিষয়: আমি দৃ that়রূপে কেবলমাত্র তার জন্য বৈশিষ্ট্যগুলি ব্যবহার করতে পছন্দ করি: বৈশিষ্ট্য; আপনি পেতে পারেন এবং / অথবা সেট করতে পারেন যে সাধারণ মান মানে। প্রকৃত কাজটি করা হচ্ছে যখন আমি ফাংশন (বা পদ্ধতি) ব্যবহার । হতে পারে কোনও কিছু গণনা করতে হবে বা ডিস্ক থেকে বা একটি ডাটাবেস থেকে পড়তে হবে: এই ক্ষেত্রে আমি একটি ফাংশন ব্যবহার করি, এমনকি যখন কেবল একটি সাধারণ মান ফিরে আসে। এইভাবে আমি সহজেই দেখতে পাচ্ছি যে কোনও কল সস্তা (সম্পত্তি) বা সম্ভবত ব্যয়বহুল (ফাংশন) কিনা।

অ্যাপল যখন কিছু সুইফ্ট কোডিং কনভেনশন প্রকাশ করে তখন আমরা সম্ভবত আরও স্পষ্টতা পাব।


12

ঠিক আছে, আপনি কোটলিনের পরামর্শ https://kotlinlang.org/docs/references/coding-conventions.html#function-vs-properties প্রয়োগ করতে পারেন ।

কিছু ক্ষেত্রে কোনও যুক্তি ছাড়াই ফাংশনগুলি কেবল পঠনযোগ্য বৈশিষ্ট্যগুলির সাথে বিনিময়যোগ্য হতে পারে। যদিও শব্দার্থকগুলি একই রকম, তবে কখন একে অপরকে পছন্দ করবেন সে সম্পর্কে কিছু স্টাইলিস্টিক সম্মেলন রয়েছে।

অন্তর্নিহিত অ্যালগরিদম যখন একটি ফাংশন উপর একটি সম্পত্তি পছন্দ করুন:

  • নিক্ষেপ করে না
  • জটিলতা গণনা করার জন্য সস্তা (বা প্রথম দফায় সংঘটিত)
  • অনুরোধের উপর একই ফল দেয়

4
"একটি ও (1) রয়েছে" পরামর্শটি আর সেই পরামর্শের অন্তর্ভুক্ত নয়।
ডেভিড পেটিগ্রু

কোটলিনের পরিবর্তনগুলি প্রতিবিম্বিত করার জন্য সম্পাদিত।
কার্স্টেন হেগম্যান

11

সাধারণভাবে গণনীয় বৈশিষ্ট্য বনাম পদ্ধতিগুলির প্রশ্নটি শক্ত এবং বিষয়বহুল হলেও বর্তমানে সম্পত্তিগুলির চেয়ে পদ্ধতির পছন্দকে প্রাধান্য দেওয়ার ক্ষেত্রে সুইফটের ক্ষেত্রে একটি গুরুত্বপূর্ণ যুক্তি রয়েছে। আপনি সুইফটে পদ্ধতিগুলি খাঁটি ফাংশন হিসাবে ব্যবহার করতে পারেন যা বৈশিষ্ট্যের ক্ষেত্রে সত্য নয় (সুইফট ২.০ বিটা হিসাবে)। এটি পদ্ধতিগুলিকে আরও কার্যকর এবং দরকারী করে যেহেতু তারা কার্যকরী রচনায় অংশ নিতে পারে।

func fflat<A, R>(f: (A) -> () -> (R)) -> (A) -> (R) {
    return { f($0)() }
}

func fnot<A>(f: (A) -> Bool) -> (A) -> (Bool) {
    return { !f($0) }
}

extension String {
    func isEmptyAsFunc() -> Bool {
        return isEmpty
    }
}

let strings = ["Hello", "", "world"]

strings.filter(fnot(fflat(String.isEmptyAsFunc)))

4
strings.filter {! $ (0) .isEmpty} - একই ফলাফল দেয়। এটি অ্যারে.ফিল্টার () এ আপেল ডকুমেন্টেশন থেকে নমুনা পরিবর্তিত হয়েছে। এবং এটি বুঝতে আরও অনেক সহজ।
poGUIst

7

রানটাইম একই হওয়ায় এই প্রশ্নটি ওজেক্টিভ-সি-তেও প্রযোজ্য। আমি বলব, আপনি যে সম্পত্তি পেয়েছেন তা দিয়ে

  • একটি সাবক্লাসে একটি সেটার যুক্ত করার সম্ভাবনা, সম্পত্তি তৈরি করে readwrite
  • didSetপরিবর্তন বিজ্ঞপ্তিগুলির জন্য কেভিও / ব্যবহার করার ক্ষমতা
  • আরও সাধারণভাবে, আপনি কী কী পাথগুলি আশা করে এমন পদ্ধতিতে সম্পত্তি সরবরাহ করতে পারেন, উদাহরণস্বরূপ আনতে অনুরোধ বাছাই

সুইফট সম্পর্কিত নির্দিষ্ট কিছু হিসাবে, আমার কাছে একমাত্র উদাহরণ হ'ল আপনি @lazyকোনও সম্পত্তির জন্য ব্যবহার করতে পারেন ।


7

একটি পার্থক্য আছে: আপনি যদি কোনও সম্পত্তি ব্যবহার করেন তবে আপনি শেষ পর্যন্ত এটিকে ওভাররাইড করতে পারেন এবং এটি একটি সাবক্লাসে পড়তে / লিখতে সক্ষম করতে পারেন।


9
আপনি কার্যগুলিও ওভাররাইড করতে পারেন। অথবা লেখার ক্ষমতা সরবরাহ করতে একটি সেটার যুক্ত করুন।
জোহানেস ফারেনক্রুগ

বেস ক্লাসটি কোনও ক্রিয়াকলাপ হিসাবে নামটি সংজ্ঞায়িত করার সময় আপনি একটি সেটার যুক্ত করতে পারেন বা কোনও সঞ্চিত সম্পত্তি সংজ্ঞা দিতে পারেন? এটি কোনও সম্পত্তি সংজ্ঞায়িত করতে পারলে অবশ্যই আপনি এটি করতে পারেন (এটি হ'ল আমার বক্তব্য) তবে আমি মনে করি না যে এটি কোনও ফাংশন সংজ্ঞায়িত করলে আপনি এটি করতে পারবেন।
অ্যানালগ ফাইল

একবার সুইফ্টের ব্যক্তিগত সম্পত্তি থাকলে (এখানে দেখুন স্ট্যাকওভারফ্লো.com/ a/ 24012515/171933 ), আপনি সেই ব্যক্তিগত সম্পত্তিটি সেট করতে কেবল আপনার সাবক্লাসে একটি সেটার ফাংশন যুক্ত করতে পারেন। যখন আপনার গিটার ফাংশনটিকে "নাম" বলা হয়, তখন আপনার সেটারটিকে "সেটনাম" বলা হত, সুতরাং নামকরণের বিরোধ নেই।
জোহানেস ফারেনক্রুগ

আপনি এটি ইতিমধ্যে করতে পারেন (পার্থক্যটি হ'ল আপনি সমর্থনের জন্য যে সঞ্চিত সম্পত্তি ব্যবহার করেন তা সর্বজনীন হবে)। তবে ওপি জিজ্ঞাসা করেছে যে কেবলমাত্র পঠনযোগ্য সম্পত্তি বা বেসে কোনও কার্যকারিতা ঘোষণার মধ্যে পার্থক্য রয়েছে কি না। আপনি যদি কেবল পঠনযোগ্য সম্পত্তি হিসাবে ঘোষণা করেন তবে আপনি এটি কোনও উত্পন্ন শ্রেণিতে পাঠ্য-লিখন করতে পারবেন। একটি এক্সটেনশান যে যোগ করে willSetএবং didSetকরতে বেস বর্গ, ভবিষ্যতে উদ্ভূত ক্লাস কিছু না জেনেই, উপেক্ষিত সম্পত্তি পরিবর্তন সনাক্ত করা সম্ভব। তবে আপনি ফাংশন দিয়ে এমন কিছু করতে পারবেন না, আমি মনে করি।
অ্যানালগ ফাইল

আপনি কীভাবে একটি সেটার যুক্ত করতে কেবল পঠনযোগ্য সম্পত্তিটিকে ওভাররাইড করতে পারেন? ধন্যবাদ আমি ডক্সে এটি দেখতে পাচ্ছি, "আপনি আপনার সাবক্লাস সম্পত্তি ওভাররাইডে গেটর এবং সেটটার উভয়ই সরবরাহ করে একটি উত্তরাধিকারসূত্রে পঠনযোগ্য সম্পত্তি কেবল পঠন-লিখনের সম্পত্তি হিসাবে উপস্থাপন করতে পারেন" তবে ... সেটারটি কী পরিবর্তনশীল লিখবে?
ড্যান রোজনস্টার্ক

5

শুধুমাত্র পাঠযোগ্য ক্ষেত্রে, একটি কম্পিউটেড সম্পত্তি উচিত না শব্দার্থগতভাবে একটি পদ্ধতি সমতূল্য বিবেচনা করা, এমনকি যখন তারা অভিন্নরুপে আচরণ, কারণ ড্রপ funcঘোষণা পরিমাণে যে গঠিত মধ্যে পার্থক্য blurs রাষ্ট্র একটি দৃষ্টান্ত ও পরিমাণে যে নিছক হয় ফাংশন এর অবস্থা. আপনি ()কল সাইটে টাইপিং সংরক্ষণ করুন , তবে আপনার কোডে স্পষ্টতা হারাতে ঝুঁকিপূর্ণ।

তুচ্ছ উদাহরণ হিসাবে, নিম্নলিখিত ভেক্টরের ধরণটি বিবেচনা করুন:

struct Vector {
    let x, y: Double
    func length() -> Double {
        return sqrt(x*x + y*y)
    }
}

একটি পদ্ধতি হিসাবে দৈর্ঘ্য ঘোষণার মাধ্যমে, এটি স্পষ্ট যে এটি রাষ্ট্রের একটি ফাংশন, যা কেবলমাত্র xএবং উপর নির্ভর করে y

অন্যদিকে, আপনি যদি lengthএকটি গণিত সম্পত্তি হিসাবে প্রকাশ করা হয়

struct VectorWithLengthAsProperty {
    let x, y: Double
    var length: Double {
        return sqrt(x*x + y*y)
    }
}

তারপর আপনি একটি দৃষ্টান্ত উপর বিন্দু-ট্যাব-সম্পূর্ণ আপনার IDE তে VectorWithLengthAsProperty, এটা দেখাবে যেন x, y, lengthএকটি সমান পথ, যা ধারণার দিক থেকে ভুল উপর বৈশিষ্ট্য ছিল।


4
এটি আকর্ষণীয়, তবে আপনি কি এই উদাহরণটি দিতে পারেন যে এই নীতিটি অনুসরণ করার সময় কেবল গণনাযোগ্য পঠনযোগ্য সম্পত্তি ব্যবহৃত হবে ? হতে পারে আমি ভুল, কিন্তু আপনার যুক্তি থেকে মনে হয় যে সেগুলি কখনই ব্যবহার করা উচিত নয় , কারণ সংজ্ঞা অনুসারে একটি গণনাযোগ্য কেবল পঠনযোগ্য সম্পত্তি কখনই রাষ্ট্রের অন্তর্ভুক্ত হয় না।
স্টুয়ার্ট

2

এমন পরিস্থিতি রয়েছে যেখানে আপনি সাধারণ ফাংশনগুলির চেয়ে গণিত সম্পত্তি পছন্দ করবেন। যেমন: কোনও ব্যক্তির পুরো নাম ফিরিয়ে দেওয়া। আপনি ইতিমধ্যে প্রথম নাম এবং শেষ নামটি জানেন। তাই সত্যিইfullName সম্পত্তি সম্পত্তি একটি ফাংশন নয়। এই ক্ষেত্রে এটি গণনা করা সম্পত্তি (কারণ আপনি পুরো নামটি সেট করতে পারবেন না, আপনি কেবলমাত্র নাম এবং পদবি ব্যবহার করে এটি বের করতে পারেন)

class Person{
    let firstName: String
    let lastName: String
    init(firstName: String, lastName: String){
        self.firstName = firstName
        self.lastName = lastName
    }
    var fullName :String{
        return firstName+" "+lastName
    }
}
let william = Person(firstName: "William", lastName: "Kinaan")
william.fullName //William Kinaan

1

পারফরম্যান্স দৃষ্টিকোণ থেকে, কোন পার্থক্য মনে হয়। যেমন আপনি দেখতে পারেন বেঞ্চমার্ক ফলাফল।

গিস্ট

main.swift টুকিটাকি সংকেতলিপি:

import Foundation

class MyClass {
    var prop: Int {
        return 88
    }

    func foo() -> Int {
        return 88
    }
}

func test(times: u_long) {
    func testProp(times: u_long) -> TimeInterval {
        let myClass = MyClass()
        let starting = Date()
        for _ in 0...times {
            _ = myClass.prop
        }
        let ending = Date()
        return ending.timeIntervalSince(starting)
    }


    func testFunc(times: u_long) -> TimeInterval {
        let myClass = MyClass()
        let starting = Date()
        for _ in 0...times {
            _ = myClass.prop
        }
        let ending = Date()
        return ending.timeIntervalSince(starting)
    }

    print("prop: \(testProp(times: times))")
    print("func: \(testFunc(times: times))")
}

test(times: 100000)
test(times: 1000000)
test(times: 10000000)
test(times: 100000000)

আউটপুট:

prop: 0.0380070209503174 func: 0.0350250005722046 prop: 0.371925950050354 func: 0.363085985183716 prop: 3.4023300409317 func: 3.38373708724976 prop: 33.5842199325562 func: 34.8433820009232 Program ended with exit code: 0

চার্টে:

মাপকাঠি


4
Date()এটি বেঞ্চমার্কের জন্য উপযুক্ত নয় কারণ এটি কম্পিউটার ঘড়ি ব্যবহার করে, যা অপারেটিং সিস্টেমের দ্বারা স্বয়ংক্রিয় আপডেটের সাপেক্ষে। mach_absolute_timeআরও নির্ভরযোগ্য ফলাফল পেতে হবে।
ক্রিশটিক

1

শব্দার্থগতভাবে বলতে গেলে, গণিত বৈশিষ্ট্যগুলি দৃ the়ভাবে অবজেক্টের অভ্যন্তরীণ অবস্থার সাথে মিলিত হওয়া উচিত - যদি অন্য বৈশিষ্ট্যগুলি পরিবর্তন না হয়, তবে বিভিন্ন সময়ে গণিত সম্পত্তি অনুসন্ধান করা একই আউটপুট প্রদান করতে হবে (== বা === মাধ্যমে তুলনীয়) - অনুরূপ যে বস্তুর উপর একটি খাঁটি ফাংশন কল করতে।

অন্যদিকে পদ্ধতিগুলি এই ধারণাটি সহ বাক্স থেকে বেরিয়ে আসে যে আমরা সবসময় একই ফলাফল পেতে পারি না, কারণ সুইফ্টের কার্যগুলি খাঁটি হিসাবে চিহ্নিত করার উপায় নেই। এছাড়াও, ওওপিতে পদ্ধতিগুলি ক্রিয়া হিসাবে বিবেচিত হয়, যার অর্থ এটি কার্যকর করে পার্শ্ব প্রতিক্রিয়া হতে পারে। যদি পদ্ধতিটির কোনও পার্শ্ব প্রতিক্রিয়া না থাকে তবে এটি নিরাপদে একটি গণিত সম্পত্তিতে রূপান্তর করা যেতে পারে।

নোট করুন যে উপরের দুটি বিবৃতি নিখুঁতভাবে শব্দার্থক দৃষ্টিকোণ থেকে, কারণ এটি গণনা করা সম্পত্তিগুলির পার্শ্ব প্রতিক্রিয়াগুলি ঘটতে পারে যা আমরা প্রত্যাশা করি না এবং পদ্ধতিগুলি খাঁটি হতে পারে well


0

Icallyতিহাসিকভাবে বর্ণনাটি এনএসবজেক্টের একটি সম্পত্তি এবং অনেকেই আশা করবেন যে এটি সুইফটে একই অব্যাহত থাকবে। পেরেন যুক্ত হওয়ার পরে এটি কেবল বিভ্রান্তি যোগ করবে।

সম্পাদনা: ক্রোধহীন ডাউনভোটিংয়ের পরে আমাকে কিছু পরিষ্কার করতে হবে - যদি এটি বিন্দু সিনট্যাক্সের মাধ্যমে অ্যাক্সেস করা হয়, তবে এটি একটি সম্পত্তি হিসাবে বিবেচনা করা যেতে পারে। হুডের নীচে কী তা বিচার্য নয়। আপনি ডট সিনট্যাক্স সহ সাধারণ পদ্ধতি অ্যাক্সেস করতে পারবেন না।

তদ্ব্যতীত, এই সম্পত্তিটি কল করার জন্য অতিরিক্ত প্যারেনের দরকার পড়েনি, যেমন সুইফটের ক্ষেত্রে, যা বিভ্রান্তির কারণ হতে পারে।


4
- আসলে এটিকে অযথাযথ বলে descriptionএকটি প্রয়োজন বোধ করা হয় পদ্ধতি উপর NSObjectপ্রোটোকল, এবং তাই Objective-C ব্যবহার ফিরিয়ে দেওয়া হয় [myObject description]। যাইহোক, সম্পত্তিটি descriptionকেবল একটি নিয়ন্ত্রিত উদাহরণ ছিল - আমি আরও জেনেরিক উত্তর খুঁজছি যা কোনও কাস্টম সম্পত্তি / ফাংশনের ক্ষেত্রে প্রযোজ্য।
স্টুয়ার্ট

4
কিছু স্পষ্টতার জন্য ধন্যবাদ। আমি এখনও নিশ্চিত নই যে আমি আপনার বিবৃতিতে সম্পূর্ণরূপে একমত যে যে কোনও প্যারামিটারলেস অবজেক্ট-সি পদ্ধতি যা কোনও মূল্য ফেরত দেয় তাকে সম্পত্তি হিসাবে বিবেচনা করা যায়, যদিও আমি আপনার যুক্তি বুঝতে পারি না। আমি আপাতত আমার ডাউন ভোটটি প্রত্যাহার করব, তবে আমি মনে করি যে উত্তরটি ইতিমধ্যে প্রশ্নটিতে উল্লিখিত 'শব্দার্থবিজ্ঞান' কারণ বর্ণনা করছে এবং আন্তঃভাষার ধারাবাহিকতা এখানে আসলেই সমস্যা নয়।
স্টুয়ার্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.