কেবল পঠনযোগ্য এবং অ-গণিত পরিবর্তনশীল বৈশিষ্ট্য সুইফটে


126

আমি নতুন অ্যাপল সুইফট ভাষা দিয়ে কিছু বের করার চেষ্টা করছি। ধরা যাক আমি উদ্দেশ্য-সি তে নিম্নলিখিতগুলির মতো কিছু করতাম। আমার readonlyসম্পত্তি আছে এবং সেগুলি স্বতন্ত্রভাবে পরিবর্তন করা যায় না। তবে, একটি নির্দিষ্ট পদ্ধতি ব্যবহার করে বৈশিষ্ট্যগুলি লজিক্যাল পদ্ধতিতে পরিবর্তন করা হয় are

আমি নীচের উদাহরণটি গ্রহণ করি, খুব সাধারণ একটি ঘড়ি। আমি এটা উদ্দেশ্য উদ্দেশ্য সি লিখতে হবে।

@interface Clock : NSObject

@property (readonly) NSUInteger hours;
@property (readonly) NSUInteger minutes;
@property (readonly) NSUInteger seconds;

- (void)incrementSeconds;

@end

@implementation Clock

- (void)incrementSeconds {
     _seconds++;

     if (_seconds == 60) {
        _seconds = 0;
        _minutes++;

         if (_minutes == 60) {
            _minutes = 0;
            _hours++;
        }
    }
}

@end

একটি নির্দিষ্ট উদ্দেশ্যে, আমরা সরাসরি সেকেন্ড, মিনিট এবং ঘন্টা স্পর্শ করতে পারি না এবং এটি কেবল একটি পদ্ধতি ব্যবহার করে দ্বিতীয় সেকেন্ডে বৃদ্ধি করার অনুমতি দেয়। কেবলমাত্র এই পদ্ধতিটি উদাহরণের পরিবর্তনশীলগুলির কৌশল ব্যবহার করে মানগুলি পরিবর্তন করতে পারে।

যেহেতু সুইফটে এ জাতীয় কোনও জিনিস নেই, তাই আমি একটি সমতুল্য অনুসন্ধান করার চেষ্টা করছি। আমি যদি এটি করি:

class Clock : NSObject {

    var hours:   UInt = 0
    var minutes: UInt = 0
    var seconds: UInt = 0

    func incrementSeconds() {

        self.seconds++

        if self.seconds == 60 {

            self.seconds = 0
            self.minutes++

            if self.minutes == 60 {

                self.minutes = 0
                self.hours++
            }
        }
    }
}

এটি কাজ করবে, তবে যে কেউ সরাসরি সম্পত্তি পরিবর্তন করতে পারে।

হয়তো আমি ইতিমধ্যে উদ্দেশ্য-সি তে একটি খারাপ নকশা পেয়েছি এবং সে কারণেই সম্ভাব্য নতুন সুইফ্টের সমতুল্য তা বোঝায় না। যদি না হয় এবং যদি কারও উত্তর থাকে, আমি খুব কৃতজ্ঞ হব;)

ভবিষ্যতে অ্যাপল দ্বারা প্রতিশ্রুতি দেওয়া অ্যাক্সেস কন্ট্রোল প্রক্রিয়াগুলির উত্তর কি?

ধন্যবাদ!


2
অ্যাক্সেস নিয়ন্ত্রণ উত্তর। প্রকৃত ডেটার জন্য ব্যক্তিগত সম্পত্তি ব্যবহার করার সময় আপনি কেবলমাত্র পঠনযোগ্য গণিত বৈশিষ্ট্য তৈরি করতে পারবেন।
লিও নাটান

এটি কীভাবে নিখরচায় রয়েছে তা অ্যাপলকে জানানোর জন্য একটি বাগ রিপোর্ট (বর্ধন) খোলার বিষয়টি নিশ্চিত করুন।
লিও নাটান

1
নতুন ব্যবহারকারীদের জন্য: নীচে স্ক্রোল করুন ...
গুস্তাফ রোজেনব্লাদ

2
@ ইথানের উত্তরটিকে সঠিক হিসাবে চিহ্নিত করুন।
ফাতেমন

উত্তর:


356

সম্পত্তির ঘোষণাটি কেবল এর সাথে উপসর্গ করুন private(set):

public private(set) var hours:   UInt = 0
public private(set) var minutes: UInt = 0
public private(set) var seconds: UInt = 0

privateএটি একটি উত্স ফাইলে internalস্থানীয় রাখে এবং মডিউল / প্রকল্পে স্থানীয় রাখে।

private(set)একটি read-onlyসম্পত্তি তৈরি করে private, setএবং উভয় সেট করে এবং getব্যক্তিগত করে।


28
কোনও উত্স ফাইলে স্থানীয় রাখার জন্য "ব্যক্তিগত", এটি মডিউল / প্রকল্পে স্থানীয় রাখতে "অভ্যন্তরীণ"। ব্যক্তিগত (সেট) সেটটি ব্যক্তিগত করে private প্রাইভেট উভয়ই সেট করে এবং ফাংশনগুলিকে ব্যক্তিগত করে তোলে
user965972

3
এটি আরও সম্পূর্ণ করার জন্য এই মন্তব্যে প্রথম মন্তব্য যুক্ত করা উচিত।
রব নরব্যাক

এই মুহুর্তে (সুইফট ৩.০.১) অ্যাক্সেস নিয়ন্ত্রণের স্তরগুলি পরিবর্তিত হয়েছে: "ফাইলপ্রাইভেট" ঘোষণাটি ঘোষণার মতো একই উত্স ফাইলে কেবল কোড দ্বারা অ্যাক্সেস করা যায় "। "ব্যক্তিগত" ঘোষণাপত্রের ঘোষণার তাত্ক্ষণিক বন্ধের সুযোগের মধ্যে কেবল কোড দ্বারা অ্যাক্সেস করা যায়।
জুরাসিক

20

আপনি যা চান তা করার দুটি প্রাথমিক উপায় রয়েছে। প্রথম উপায় হ'ল ব্যক্তিগত সম্পত্তি এবং একটি সরকারী গণিত সম্পত্তি যা এই সম্পত্তিটি ফেরত দেয়:

public class Clock {

  private var _hours = 0

  public var hours: UInt {
    return _hours
  }

}

কিন্তু এই একটি ভিন্ন, খাটো ভাবে অর্জন করা যেতে পারে যেমন ধারায় বর্ণিত "অ্যাক্সেস কন্ট্রোল" এর "সুইফট প্রোগ্রামিং ভাষা" বই:

public class Clock {

    public private(set) var hours = 0

}

পার্শ্ব নোট হিসাবে, আপনি কোনও পাবলিক ধরণের ঘোষণার সময় একটি সর্বজনীন সূচনা প্রদান করা আবশ্যক। এমনকি যদি আপনি সমস্ত বৈশিষ্ট্যে ডিফল্ট মান সরবরাহ করেন তবে init()অবশ্যই তা অবশ্যই প্রকাশ্য হিসাবে সংজ্ঞায়িত করা উচিত:

public class Clock {

    public private(set) var hours = 0

    public init() {
      hours = 0
    }
    // or simply `public init() {}`

}

এটিও বইয়ের একই বিভাগে ব্যাখ্যা করা হয়েছে, যখন ডিফল্ট আরম্ভকারীদের কথা বলি।


5

যেহেতু কোনও অ্যাক্সেস নিয়ন্ত্রণ নেই (যার অর্থ আপনি যে কোনও কলকারী তার উপর নির্ভর করে কোনও অ্যাক্সেস চুক্তি করতে পারবেন না), এখনই আমি কী করব তা এখানে:

class Clock {
    struct Counter {
        var hours = 0;
        var minutes = 0;
        var seconds = 0;
        mutating func inc () {
            if ++seconds >= 60 {
                seconds = 0
                if ++minutes >= 60 {
                    minutes = 0
                    ++hours
                }
            }
        }
    }
    var counter = Counter()
    var hours : Int { return counter.hours }
    var minutes : Int { return counter.minutes }
    var seconds : Int { return counter.seconds }
    func incrementTime () { self.counter.inc() }
}

এটি কেবলমাত্র কাউন্টারে সরাসরি অ্যাক্সেসের জন্য এক মাত্রার ইন্ডিয়ারেশন যুক্ত করে; অন্য শ্রেণি একটি ঘড়ি তৈরি করতে পারে এবং তারপরে সরাসরি এটির কাউন্টারে অ্যাক্সেস করতে পারে। তবে ধারণাটি - যেমন, আমরা যে চুক্তিটি করার চেষ্টা করছি - তা হ'ল অন্য শ্রেণীর কেবল ক্লকের শীর্ষ স্তরের বৈশিষ্ট্য এবং পদ্ধতিগুলি ব্যবহার করা উচিত। আমরা সেই চুক্তিটি প্রয়োগ করতে পারি না , তবে বাস্তবে-সিতেও এটি প্রয়োগ করা বেশ অসম্ভব ছিল।


দেখে মনে হচ্ছে এর পর থেকে এই পরিবর্তন হয়েছে, তাই না? বিকাশকারী.অ্যাপল.
com/swift/blog/?id=5

1
@ ইয়ার নিশ্চিত, সুইফটে অ্যাক্সেস নিয়ন্ত্রণ যুক্ত হওয়ার অনেক আগে এই পুরো প্রশ্ন / উত্তরটি লেখা হয়েছিল written এবং সুইফটটি এখনও বিকশিত হচ্ছে, সুতরাং উত্তরগুলি পুরানো হতে থাকবে।
ম্যাট

2

আসলে প্রবেশাধিকার নিয়ন্ত্রণ (যা সুইফট এখনও বিদ্যমান নয়) হিসাবে কার্যকরী হয় না আপনি উদ্দেশ্য সি লোকেরা মনে হতে পারে যেমন পারেন সরাসরি আপনার Readonly ভেরিয়েবল পরিবর্তন, যদি তারা সত্যিই চাই। তারা কেবল শ্রেণীর পাবলিক ইন্টারফেস দিয়ে এটি করে না।

আপনি সুইফটে অনুরূপ কিছু করতে পারেন (আপনার কোডটি কেটে পেস্ট করুন এবং কিছু সংশোধন করুন, আমি এটি পরীক্ষা করিনি):

class Clock : NSObject {

    var _hours:   UInt = 0
    var _minutes: UInt = 0
    var _seconds: UInt = 0

    var hours: UInt {
    get {
      return _hours
    }
    }

    var minutes: UInt {
    get {
      return _minutes
    }
    }

    var seconds: UInt  {
    get {
      return _seconds
    }
    }

    func incrementSeconds() {

        self._seconds++

        if self._seconds == 60 {

            self._seconds = 0
            self._minutes++

            if self._minutes == 60 {

                self._minutes = 0
                self._hours++
            }
        }
    }
}

প্রকৃত সঞ্চিত বৈশিষ্ট্যগুলি জনসাধারণের ইন্টারফেসে দৃশ্যমান হওয়া ব্যতীত আপনি অবজেক্টিভ সিতে যা আছে তার সমান।

দ্রুতগতিতে আপনি আরও আকর্ষণীয় কিছু করতে পারেন, যা আপনি উদ্দেশ্য সিতেও করতে পারেন, তবে এটি সম্ভবত দ্রুতগতিতে সুন্দর (ব্রাউজারে সম্পাদিত, আমি এটি পরীক্ষা করিনি):

class Clock : NSObject {

    var hours: UInt = 0

    var minutes: UInt {
    didSet {
      hours += minutes / 60
      minutes %= 60
    }
    }

    var seconds: UInt  {
    didSet {
      minutes += seconds / 60
      seconds %= 60
    }
    }

    // you do not really need this any more
    func incrementSeconds() {
        seconds++
    }
}

"লোকেরা সরাসরি আপনার পঠনযোগ্য ভেরিয়েবলগুলি সংশোধন করতে পারে" - আপনার সঠিক অর্থ কী? কিভাবে?
ব্যবহারকারী 1244109

আমি অবজেক্টিভ সি-কে উল্লেখ করছিলাম অবজেক্টিভ সি-তে আপনি উদ্দেশ্য সি রানটাইম এপিআইয়ের মাধ্যমে একটি শ্রেণি সম্পর্কে সমস্ত কিছুতে গতিশীল অ্যাক্সেস পেয়ে গেছেন।
অ্যানালগ ফাইল

আমি একরকম বুঝতে পেরেছি যে তাড়াহুড়ো করে। কৌতুহল পেয়েছি। ধন্যবাদ
ব্যবহারকারী 1244109
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.