কীভাবে কনস্ট্রাক্টর কাজ করবেন?


111

আমি লক্ষ্য করেছি যে ডার্টে কনস্ট্রাক্টর তৈরি করা সম্ভব। ডকুমেন্টেশনে, এটি বলে যে constশব্দটি একটি সংকলন সময় ধ্রুবক বোঝাতে ব্যবহৃত হয়।

আমি ভাবছিলাম যখন আমি constকোনও অবজেক্ট তৈরির জন্য কনস্ট্রাক্টর ব্যবহার করি তখন কী হয় happens এটি কি কোনও স্থাবর বস্তুর মতো যা সর্বদা একই এবং সংকলনের সময়ে পাওয়া যায়? constকনস্ট্রাক্টর ধারণাটি আসলে কীভাবে কাজ করে? একটি কেমন আছে const কন্সট্রাকটর একটি থেকে আলাদা নিয়মিত কন্সট্রাকটর?

উত্তর:


78

কনস্ট্রাক্টর একটি "ক্যানোনিকালাইজড" উদাহরণ তৈরি করে।

এটি হ'ল, সমস্ত ধ্রুবক এক্সপ্রেশনগুলি ক্যানোনিকালাইজড শুরু হয় এবং পরে এই "ধরণের" চিহ্নগুলি এই ধ্রুবকের সমতুল্যতা স্বীকৃতি হিসাবে ব্যবহৃত হয়।

ক্যাননিকাল:

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


এর অর্থ দাঁড়ায় যে কনস্ট্যান্ট এক্সপ্রেশনগুলির মতো const Foo(1, 1)ভার্চুয়াল মেশিনের তুলনায় কার্যকর যে কোনও ব্যবহারযোগ্য ফর্ম উপস্থাপন করতে পারে।

ভিএমকে কেবলমাত্র এই ধরণের অভিব্যক্তিটি ঘটে সে অনুসারে মানের ধরণ এবং তর্কগুলি বিবেচনায় নেওয়া দরকার। এবং অবশ্যই, সেগুলি অপ্টিমাইজেশনের জন্য হ্রাস পেয়েছে।

একই আধ্যাত্মিক মান সহ ধ্রুবক:

var foo1 = const Foo(1, 1); // #Foo#int#1#int#1
var foo2 = const Foo(1, 1); // #Foo#int#1#int#1

বিভিন্ন আধ্যাত্মিক মানযুক্ত ধ্রুবকগুলি (কারণ স্বাক্ষরগুলি পৃথক হয়):

var foo3 = const Foo(1, 2); // $Foo$int$1$int$2
var foo4 = const Foo(1, 3); // $Foo$int$1$int$3

var baz1 = const Baz(const Foo(1, 1), "hello"); // $Baz$Foo$int$1$int$1$String$hello
var baz2 = const Baz(const Foo(1, 1), "hello"); // $Baz$Foo$int$1$int$1$String$hello

কনস্ট্যান্ট প্রতিবার পুনরায় তৈরি করা হয় না। এগুলি সংকলনের সময় ক্যানোনিকালাইজ করা হয় এবং বিশেষ অনুসন্ধানের টেবিলগুলিতে (যেখানে তারা তাদের স্বীকৃত স্বাক্ষর দ্বারা হ্যাশ করা হয়) সংরক্ষণ করা হয় যার থেকে পরে তারা পুনরায় ব্যবহার করা হয়।

পুনশ্চ

#Foo#int#1#int#1এই নমুনাগুলিতে ব্যবহৃত ফর্মটি কেবল তুলনামূলক উদ্দেশ্যে ব্যবহৃত হয় এবং এটি ডার্ট ভিএম-তে ক্যানোনিকালাইজেশন (উপস্থাপনা) এর আসল রূপ নয়;

তবে আসল ক্যানোনিকালাইজেশন ফর্মটি অবশ্যই "স্ট্যান্ডার্ড" ক্যানোনিকাল উপস্থাপনা হতে হবে।


80

আমি ক্রিস স্টর্মস ব্লগে লাসির উত্তরটি একটি দুর্দান্ত ব্যাখ্যা পেয়েছি।

ডার্ট কনস্ট্যান্ট কনস্ট্রাক্টর

আমি আশা করি যে তারা কন্টেন্টটি অনুলিপি করবেন তাতে তাদের আপত্তি নেই।

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

ডার্টে একটি ক্ষেত্রটি হ'ল একটি বেনামে স্টোরেজ অবস্থান যা একটি স্বয়ংক্রিয়ভাবে তৈরি গেটর এবং সেটারের সাথে মিলিত হয় যা স্টোরেজটি পড়ে এবং আপডেট করে এবং এটি কোনও নির্মাণকারীর আরম্ভকারী তালিকায় আরম্ভও করা যেতে পারে।

একটি চূড়ান্ত ক্ষেত্র একই, কেবল সেটার ব্যতীত, সুতরাং এর মান নির্ধারণের একমাত্র উপায়টি কনস্ট্রাক্টর আরম্ভকারী তালিকায় রয়েছে এবং এর পরে মান পরিবর্তন করার কোনও উপায় নেই - সুতরাং "চূড়ান্ত"।

কনস্ট্রাক্ট কনস্ট্রাক্টরগুলির পয়েন্টটি চূড়ান্ত ক্ষেত্রগুলি আরম্ভ করার নয়, যে কোনও জেনারেটর কনস্ট্রাক্টর এটি করতে পারে। বিন্যাসটি কম্পাইল-টাইম ধ্রুবক মানগুলি তৈরি করা: অবজেক্টগুলি যেখানে কোনও ক্ষেত্রের মানগুলি কোনও বিবৃতি কার্যকর না করেই কমপাইল সময়ে ইতিমধ্যে জানা যায়।

যা ক্লাস এবং কনস্ট্রাক্টরকে কিছুটা বিধিনিষেধ দেয়। কনস্ট্রাক্ট কনস্ট্রাক্টরের একটি বডি থাকতে পারে না (কোনও বিবৃতি কার্যকর করা হয় না!) এবং এর শ্রেণিতে অবশ্যই কোনও চূড়ান্ত ক্ষেত্র থাকতে হবে না (সংকলনের সময় আমরা যে মূল্য "জানি" অবশ্যই এটি পরে পরিবর্তন করতে সক্ষম হবে না)। ইনিশিয়ালাইজার তালিকার ক্ষেত্রগুলি কেবলমাত্র অন্যান্য সংকলন-সময় ধ্রুবকের ক্ষেত্রেই আরম্ভ করতে হবে, তাই ডান দিকের দিকগুলি "সংকলন-সময়ের ধ্রুবক অভিব্যক্তি" এর মধ্যে সীমাবদ্ধ [1]। এবং এটি অবশ্যই "কনস্ট" এর সাথে উপস্থাপিত হওয়া উচিত - অন্যথায় আপনি কেবলমাত্র একটি সাধারণ নির্মাতা পাবেন যা এই প্রয়োজনীয়তাগুলি পূরণ করতে ঘটে। এটি পুরোপুরি ঠিক আছে, এটি কেবল কোনও নির্মাণকারী নয়।

একটি কম্পাইল-টাইম ধ্রুবক অবজেক্টটি তৈরির জন্য কনস্ট্রাক্ট কনস্ট্রাক্টর ব্যবহার করার জন্য, আপনি তারপরে "নতুন "টিকে" কনস্ট "দিয়ে" নতুন "-প্রকাশে প্রতিস্থাপন করুন। আপনি এখনও কনস্ট-কনস্ট্রাক্টরের সাথে "নতুন" ব্যবহার করতে পারেন, এবং এটি এখনও একটি অবজেক্ট তৈরি করবে, তবে এটি কেবল একটি সাধারণ নতুন অবজেক্ট হবে, সংকলিত-সময় ধ্রুবক মান নয়। এটি হ'ল: কনস্ট্রাক্টর কনস্ট্রাক্টর রানটাইমে অবজেক্ট তৈরির পাশাপাশি কমপাইল-টাইম ধ্রুবক অবজেক্টগুলি সংকলনের সময় তৈরির জন্য সাধারণ কনস্ট্রাক্টর হিসাবেও ব্যবহার করা যেতে পারে।

সুতরাং, উদাহরণ হিসাবে:

class Point { 
  static final Point ORIGIN = const Point(0, 0); 
  final int x; 
  final int y; 
  const Point(this.x, this.y);
  Point.clone(Point other): x = other.x, y = other.y; //[2] 
}

main() { 
  // Assign compile-time constant to p0. 
  Point p0 = Point.ORIGIN; 
  // Create new point using const constructor. 
  Point p1 = new Point(0, 0); 
  // Create new point using non-const constructor.
  Point p2 = new Point.clone(p0); 
  // Assign (the same) compile-time constant to p3. 
  Point p3 = const Point(0, 0); 
  print(identical(p0, p1)); // false 
  print(identical(p0, p2)); // false 
  print(identical(p0, p3)); // true! 
}

সংকলন-সময় ধ্রুবকগুলি ক্যানোনিকালাইজড। এর অর্থ আপনি যতবার "কনস্ট পয়েন্ট (0,0)" লিখুন তা নয়, আপনি কেবল একটি অবজেক্ট তৈরি করেন। এটি কার্যকর হতে পারে - তবে এটি যতটা মনে হবে ততটা নয়, যেহেতু আপনি মানটি ধরে রাখতে পরিবর্তে পরিবর্তনশীলটি ব্যবহার করতে পারেন এবং পরিবর্তে ভেরিয়েবলটি ব্যবহার করতে পারেন।

সুতরাং, সংকলন-সময় ধ্রুবকগুলি যাইহোক ভাল?

  • তারা enums জন্য দরকারী।
  • আপনি সুইচ ক্ষেত্রে সংকলন-সময় ধ্রুবক মান ব্যবহার করতে পারেন।
  • এগুলি টিকা হিসাবে ব্যবহৃত হয়।

কম্বল-টাইম ধ্রুবকগুলি ডার্টটি অলসভাবে ভেরিয়েবলগুলি আরম্ভ করার আগে আরও গুরুত্বপূর্ণ হিসাবে ব্যবহৃত হত। তার আগে, আপনি কেবলমাত্র "var x = foo" এর মতো একটি প্রাথমিক গ্লোবাল ভেরিয়েবল ঘোষণা করতে পারতেন; যদি "foo" একটি সংকলন-সময় ধ্রুবক ছিল। যে প্রয়োজন ছাড়াই, বেশিরভাগ প্রোগ্রাম কোনও কনস্ট অবজেক্ট ব্যবহার না করেই লেখা যায়

সুতরাং, সংক্ষিপ্ত সংক্ষিপ্তসার: কনস্ট্রাক্টর কনস্ট্রাক্টরগুলি কেবল সংকলন-সময় ধ্রুবক মান তৈরি করার জন্য।

/ এল

[1] বা সত্যই: "সম্ভাব্য সংকলন-ধ্রুবক অভিব্যক্তি সংকলন" কারণ এটি নির্মাণকারীর পরামিতিগুলিকেও উল্লেখ করতে পারে। [2] সুতরাং হ্যাঁ, একটি শ্রেণীর একই সাথে উভয় কনস্ট্যান্ড এবং নন-কনস্ট্রাক্টর কনস্ট্রাক্টর থাকতে পারে।

এই বিষয়টি https://github.com/dart-lang/sdk/issues/36079 এ কিছু আকর্ষণীয় মন্তব্যে নিয়েও আলোচনা করা হয়েছিল ।


এএফআইএইকে কনস্ট এবং চূড়ান্তভাবে আরও অনুকূলিত জেএস তৈরি করতে দেয়।
গন্টার জ্যাচবাউয়ার

2
এগুলি পদ্ধতি স্বাক্ষরে ডিফল্ট-মানগুলির জন্যও কার্যকর are
ফ্লোরিয়ান লোয়েশ

1
কেউ আমাকে বোঝাতে পারেন যে এই লাইনটি কীভাবে কাজ করে? Point.clone(Point other): x = other.x, y = other.y;
দক্ষিণ গার্গাস

কোন অংশটি অস্পষ্ট? এটি সম্পর্কিত বলে মনে হচ্ছে নাconst
গন্টার জ্যাচবাউর

3
constমিডিয়াম.com/@mehmetf_71205/inheriting- widgets- b7ac56dbbeb1 অনুসারে ফ্লটার উইজেটগুলির জন্য দুর্দান্ত পারফরম্যান্সের জয় " উপ-গাছের উইজেট এবং কলগুলি বিল্ড () মূল্যবান চক্রগুলি নষ্ট করে বিশেষত যদি আপনার বিল্ড পদ্ধতিগুলি ভারী হয়। "
ডেভিড চ্যান্ডলার

8

খুব ভালভাবে বিশদে ব্যাখ্যা করা হয়েছে তবে ব্যবহারকারীদের পক্ষে যারা প্রকৃতপক্ষে কোনও কনস্ট্রাক্টর ব্যবহারকারীর সন্ধান করছেন

এটি ফ্লটার পারফরম্যান্স বাড়াতে ব্যবহৃত হয় কারণ এটি ফ্লটারকে কেবলমাত্র নতুন উইজেটগুলি পুনর্নির্মাণে সহায়তা করে State

উদাহরণ দিয়ে> -> দিয়ে ব্যাখ্যা করা যায়

    class _MyWidgetState extends State<MyWidget> {

  String title = "Title";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Column(
        children: <Widget>[
          const Text("Text 1"),
          const Padding(
            padding: const EdgeInsets.all(8.0),
            child: const Text("Another Text widget"),
          ),
          const Text("Text 3"),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          setState(() => title = 'New Title');
        },
      ),
    );
  }
}

এই উদাহরণ হিসাবে, কেবলমাত্র পাঠ্য শিরোনাম পরিবর্তন করা উচিত, সুতরাং কেবলমাত্র এই উইজেটটি পুনর্নির্মাণ করা উচিত, সুতরাং অন্য সমস্ত উইজেটগুলি কনস্ট্রাক্টর হিসাবে তৈরি করা কার্যকারিতা বৃদ্ধির জন্য ঝাঁকুনিকে একইভাবে সহায়তা করবে।


0

একটি উদাহরণ ডেমো যা কনস্ট্যান্ট উদাহরণস্বরূপ চূড়ান্ত ক্ষেত্রের দ্বারা সিদ্ধান্ত নেয়।
এবং এই ক্ষেত্রে, এটি সংকলন-সময়ে ভবিষ্যদ্বাণী করা যায় না।

import 'dart:async';

class Foo {
  final int i;
  final int j = new DateTime.now().millisecond;
  const Foo(i) : this.i = i ~/ 10;

  toString() => "Foo($i, $j)";
}



void main() {
  var f2 = const Foo(2);
  var f3 = const Foo(3);

  print("f2 == f3 : ${f2 == f3}"); // true
  print("f2 : $f2"); // f2 : Foo(0, 598)
  print("f3 : $f3"); // f3 : Foo(0, 598)

  new Future.value().then((_) {
    var f2i = const Foo(2);
    print("f2 == f2i : ${f2 == f2i}"); // false
    print("f2i : $f2i"); // f2i : Foo(0, 608)
  });
}

এখন ডার্ট এটি পরীক্ষা করবে।

ডার্ট বিশ্লেষণ:

[ডার্ট] 'কনস্ট' কনস্ট্রাক্টরকে সংজ্ঞায়িত করা যায় না কারণ ক্ষেত্র 'জ' একটি ধ্রুবক মান দিয়ে আরম্ভ করা হয়েছে

রানটাইম ত্রুটি:

/main.dart ': ত্রুটি: লাইন 5 পজ 17: এক্সপ্রেশনটি একটি বৈধ সংকলন-সময় ধ্রুবক চূড়ান্ত int নয় = নতুন তারিখটাইম.নো ()। মিলিসেকেন্ড;

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