সুইফটে স্থির ফাংশন ভেরিয়েবল


97

আমি কীভাবে স্থিতিশীল ভেরিয়েবলটিকে স্থানীয়ভাবে স্থানীয়ভাবে সুইফটের কোনও ফাংশনে ঘোষনা করতে পারি তা জানার চেষ্টা করছি।

সি-তে, এটি দেখতে এরকম কিছু দেখাবে:

int foo() {
    static int timesCalled = 0;
    ++timesCalled;
    return timesCalled;
}

উদ্দেশ্য-সি-তে, এটি মূলত:

- (NSInteger)foo {
    static NSInteger timesCalled = 0;
    ++timesCalled;
    return timesCalled;
}

তবে আমি সুইফটে এ জাতীয় কিছু করতে পারব না। আমি নিম্নলিখিত পদ্ধতিতে ভেরিয়েবল ঘোষণার চেষ্টা করেছি:

static var timesCalledA = 0
var static timesCalledB = 0
var timesCalledC: static Int = 0
var timesCalledD: Int static = 0

কিন্তু এই সমস্ত ত্রুটি ফলাফল।

  • প্রথম অভিযোগ "স্থির বৈশিষ্ট্যগুলি কেবলমাত্র কোনও ধরণের হিসাবে ঘোষণা করা যেতে পারে"।
  • দ্বিতীয়টি "প্রত্যাশিত ঘোষণা" (কোথায় static) এবং "প্রত্যাশিত প্যাটার্ন" (কোথায় timesCalledBরয়েছে) অভিযোগ করে
  • তৃতীয় অভিযোগ করে "একটি লাইনের ধারাবাহিক বিবৃতি অবশ্যই ';'" দ্বারা পৃথক করা উচিত (কোলন staticএবং "প্রত্যাশিত প্রকার" (যেখানে staticরয়েছে)
  • চতুর্থ অভিযোগ "একটি লাইন দ্বারা পৃথক করা আবশ্যক ধারাবাহিক বিবৃতি ';'" (মধ্যে স্থান Intএবং static) এবং "প্রত্যাশিত ঘোষণা" (অধীনে সমান চিহ্ন)

উত্তর:


159

আমার মনে হয় না যে সুইফট কোনও শ্রেণি / কাঠামোর সাথে সংযুক্ত না করে স্থিতিশীল পরিবর্তনশীলকে সমর্থন করে। স্ট্যাটিক ভেরিয়েবলের সাথে একটি ব্যক্তিগত কাঠামো ঘোষণার চেষ্টা করুন।

func foo() -> Int {
    struct Holder {
        static var timesCalled = 0
    }
    Holder.timesCalled += 1
    return Holder.timesCalled
}

  7> foo()
$R0: Int = 1
  8> foo()
$R1: Int = 2
  9> foo()
$R2: Int = 3

হ্যাঁ, আমি কিছুটা খেলা চালিয়ে যাচ্ছিলাম এবং এটিই ছিল মূলত আসল সমাধান solution
nhgrif

17
উত্সাহিত, তবে আমি দুঃখিত এটি আমাদের অবলম্বন করতে হবে।
Tricertops

4
প্রকারের বৈশিষ্ট্য এবং পদ্ধতিগুলি কোনও প্রকারের (যেমন একটি শ্রেণি, কাঠামো বা এনুম) এর সাথে সম্পর্কিত এবং এটি কেবলমাত্র কোনও ফাংশনের সাথে সম্পর্কিত হতে পারে না। প্রকার বৈশিষ্ট্যগুলিতে অ্যাপল ডকুমেন্টেশন । টুইটার এ সম্পর্কে আরও একটি উপায় হ'ল ফাংশনটি "ক্লাস" এ ক্লাসে রাখা, সেই শ্রেণীর জন্য একটি ধরণের সম্পত্তি তৈরি করা এবং এটি ফাংশনের অভ্যন্তরে ব্যবহার করা।
এনএসকোডার

6
@ এনএনএস কোডার তবে struct Holder {…}একাধিক ফাংশনের অভ্যন্তরে এটি ঘোষণা করা সম্ভব এবং এগুলির সংঘর্ষ হবে না। চারপাশে static letএই structবয়লারপ্লেট ছাড়া সুইফ্ট সমর্থন করতে পারে ।
ট্রাইয়ারটপস

4
@ হানি আমি দুঃখিত তবে আমি আরও আপডেট হওয়া উত্তর খুঁজে পাই না?
ব্রায়ান চেন

23

আরেকটি সমাধান

func makeIncrementerClosure() -> () -> Int {
    var timesCalled = 0
    func incrementer() -> Int {
        timesCalled += 1
        return timesCalled
    }
    return incrementer
}

let foo = makeIncrementerClosure()
foo()  // returns 1
foo()  // returns 2

4
এটি করার জন্য এটি একটি সাধারণ জাভাস্ক্রিপ্টের উপায়
ব্রায়ান চেন

4
তবে আমি যদি আবার বা () কে কল করি তবে প্রথম কলটিতে অভ্যন্তরীণ ফাংশনটি 1 প্রদান করে। এটি একটি স্ট্যাটিক ভেরিয়েবল থেকে পৃথক।
nhgrif

4
এটি এখানে অ্যাপলের ডক্সগুলিতেও শেখানো হয়: developer.apple.com/library/ios/docamentation/Swift/Concepual/… কেবল "ফাংশনাল প্রোগ্রামিং" এর সাথে লাইনে রাখার জন্য এটি সেরা সমাধান বলে মনে হয়, তবে এর অন্যান্য সমাধানও রয়েছে আমরা হব. যদিও এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
datWooWoo

4
আমি দুঃখিত, তবে এটি একই সমস্যার জন্য আরও জটিলতা যুক্ত করার মতো একটি কুরুচিপূর্ণ হ্যাক। তোমার লক্ষ্যটা কি? সেক্ষেত্রে আমি সাধারণ শ্রেণির সম্পত্তি পছন্দ করি। @ ব্রায়ান চেনের উত্তরটি আপনি পেতে পারেন এমন সবচেয়ে কাছের উত্তর। আমি তার উত্তরটি একটি ফ্লিপপ্লপ ধরণের সমাধানের জন্য ব্যবহার করি। ড্যানিয়েল সম্ভবত অ্যাপলটির সুইফ্ট প্রোগ্রামিংয়ের নিয়ম মেনে চলার পক্ষে সবচেয়ে ভাল।
আন্দালুজ

4
আমি বিশেষত এই সমাধানটি পছন্দ করেছি। এটি কোনও ফাংশনের স্কোপের অভ্যন্তরে স্থির পরিবর্তনশীল হিসাবে একই ফলাফল অর্জনের জন্য একটি উচ্চ-অর্ডার ফাংশনটি ব্যবহারের একটি নিখুঁত উদাহরণ। স্ট্যাটিক ফাংশন ভার্স ভাল কারণে স্যুইফটে সমর্থিত নয়। এটি প্রোগ্রামিংয়ের প্রাকৃতিক বিবর্তন। পুরানো ফ্যাশন পদ্ধতিতে কোড চেষ্টা করার জন্য হ্যাকগুলির প্রয়োজন। আমার মতে, ভেরিয়েবল ক্যাপচারিংয়ের বিপরীতে অতিরিক্ত নেস্টেড ডেটা টাইপ যুক্ত করা কোডের পাঠযোগ্যতা হ্রাস করে।
nstein

18

এক্সকোড 6.3 সহ সুইফট 1.2 এখন প্রত্যাশা অনুযায়ী স্থির সমর্থন করে। এক্সকোড 6.3 বিটা রিলিজ নোটগুলি থেকে:

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

এটি প্রদর্শিত হয় যে ফাংশনগুলিতে স্থির ঘোষণাপত্র থাকতে পারে না (যেমন প্রশ্নে বলা হয়েছে)। পরিবর্তে, ঘোষণাটি অবশ্যই ক্লাস পর্যায়ে করা উচিত।

ক্লাস ফাংশনটির প্রয়োজন না থাকলেও ক্লাসের (আর্স্ট স্ট্যাটিক) ফাংশনের অভ্যন্তরে বাড়ানো স্থির সম্পত্তি দেখানোর সহজ উদাহরণ:

class StaticThing
{
    static var timesCalled = 0

    class func doSomething()
    {
        timesCalled++

        println(timesCalled)
    }
}

StaticThing.doSomething()
StaticThing.doSomething()
StaticThing.doSomething()

আউটপুট:

1
2
3

4
আমি সন্দেহ করি যে staticঅ্যাপলটির অর্থের মধ্যে এই পার্থক্যটি ইচ্ছাকৃত হতে পারে যদিও পরিবর্তনের জন্য অনুরোধ করার জন্য কোনও বাগ ফাইল করা সর্বদা স্বাগত । সি, staticসীমিত স্টোরেজ , উৎস ফাইল সুযোগ করার জন্য একটি পরিবর্তনশীল (যা সবসময় বর্গ সুযোগ হিসাবে একই নয়) এর সময় পরিবর্তনশীল ঘোষণা বসানো নির্ধারণ আভিধানিক সুযোগ (অর্থাত বিশ্বব্যাপী বনাম ফাংশন মধ্যে বনাম অনেকগুলি nested- {}গুলি)। সুইফটে, স্টোরেজ স্কোপটি সর্বদা লেসিকাল স্কোপ অনুসরণ করে, সুতরাং আপনার কোনও ভেরিয়েবল থাকতে পারে না যা কোনও ফাংশনের জন্য লেক্সিকাল এবং এতে বৈশ্বিক স্টোরেজ রয়েছে।
রিক্সার

5
ড্যানিয়েল, এটি আসলে সূক্ষ্মভাবে (তবে গুরুত্বপূর্ণভাবে) প্রশ্নটি চেয়ে আলাদা different আমি যদিও উত্তর প্রশংসা করি। @ চালক আপনি কী বলছেন তা আমি বুঝতে পেরেছি এবং মনে করি আপনার প্রশ্নের উত্তর এই প্রশ্নের উত্তরের জন্য উত্তম হতে পারে।
nhgrif

@ হানগ্রিফ হ্যাঁ, আমি উত্তরে ইঙ্গিত দিয়েছি যে এটি সুনির্দিষ্ট প্রশ্নের সমাধান করে না। আমি কেবল ভাবছিলাম যে সুইফট ১.২-এর পরিবর্তনগুলি ব্যবহারের ক্ষেত্রে এটির প্রয়োজনীয়তার মূল বিষয়টিকে সম্বোধন করে (অবশ্যই প্রাক প্রাক সুইফট ১.২ এর চেয়ে ভাল গল্প)। তবে এটি মনে হচ্ছে আপনার পক্ষে ফাংশনটিতে পরিবর্তনশীল স্কোপ রাখা গুরুত্বপূর্ণ - যা বর্তমানে সম্ভব নয়।
ড্যানিয়েল

সিআই-এর @ ইষ্টক্রিটার মনে করেন স্থিতাবস্থা সর্বদা বিশ্বব্যাপী সঞ্চিত থাকে। যদিও আমি নিশ্চিত নই। আমি মনে করি অ্যাপল এখানে সমস্যাটি সমাধান করার চেষ্টা করছে। দ্রুতগতিতে, এটি এখন সর্বদা লেসিক্যাল এবং
স্টোরেজটি

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

0

আরেকটি সমাধান

class Myclass {
    static var timesCalled = 0
    func foo() -> Int {
        Myclass.timesCalled += 1
        return Myclass.timesCalled
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.