সংমিশ্রণের জন্য কেন এত খারাপ?


44

প্রত্যেকেই বলে চলেছে যে জাভাস্ক্রিপ্টের একটি সমস্যা স্ট্রিং কন্টেটিংয়ের জন্য +[ উদাহরণস্বরূপ ] ব্যবহার করছে। কেউ কেউ বলছেন যে সমস্যাটি ব্যবহার করছে না +, এটি জোর করে টাইপ করুন [পূর্ববর্তী উদাহরণ থেকে মন্তব্যগুলি দেখুন]। তবে দৃ strongly়ভাবে টাইপ করা ভাষাগুলি কোন সমস্যা ছাড়াই সংমিশ্রণ এবং জবরদস্তির ধরণের জন্য + ব্যবহার করে। উদাহরণস্বরূপ, সি # তে:

int number = 1;
MyObject obj = new MyObject();

var result = "Hello" + number + obj;
// is equivalent to
string result = "hello" + number.ToString() + obj.ToString();

তাহলে কেন এটি জাভাস্ক্রিপ্টে স্ট্রিং কনটেনটেশন এত বড় সমস্যা?


17
এটা কেন bad? কে Everyone?
নিল

3
আমি মনে করি সমস্যাটি হ'ল একটি গাণিতিক অপারেটর। এবং + এর একত্রীকরণ ফাংশন সেই মানক প্রক্রিয়াটিকে বিভ্রান্ত করে। কারণ "হ্যালো" + নম্বরে চলাকালীন সংখ্যা "হ্যালো" নাও করতে পারে।
SoylentGray

3
@ নিল, আমি একমত - আমি জানতে চাই এই সমস্ত প্রশ্নগুলিতে এই সমস্ত রহস্যময় 'অ্যালোনস' কে আছে be
গ্র্যান্ডমাস্টারবি

সংক্ষিপ্তকরণের জন্য + ব্যবহার করা ঠিক আছে। ডায়নামিক টাইপিং ব্যবহার করা ঠিক আছে। উভয়কে একই ভাষায় ব্যবহার করা খারাপ ^ H ^ H ^ H অস্পষ্টতার দিকে নিয়ে যায়।
গেরি

6
@ নিল - "প্রত্যেকে" ডগলাস ক্রকফোর্ড হবেন। তিনি এটিকে "জাভাস্ক্রিপ্ট: দ্য গুড পার্টস" বইটিতে এটি "ভয়ঙ্কর" হিসাবে তালিকাভুক্ত করেছেন।
kirk.burleson

উত্তর:


68

জাভাস্ক্রিপ্ট কোডের এই অংশটি বিবেচনা করুন:

var a = 10;
var b = 20;
console.log('result is ' + a + b);

এটি লগ হবে

ফলাফল 1020

যা সম্ভবত উদ্দেশ্যমূলক ছিল তা নয়, এবং বাগটি অনুসন্ধান করা শক্ত হতে পারে।


4
অন্তর্নিহিত সমস্যার খুব সুন্দর চিত্র: টাইপগুলি (উদাহরণস্বরূপ স্ট্রিং + ইন্ট + ইন) মিশ্রিত হয়ে গেলে স্ট্রিং কনটেনটেশন ভালভাবে সংজ্ঞায়িত হয় না। পুরোপুরি আলাদা অপারেটর (যেমন পার্লের '।') ভাল-সংজ্ঞায়িত শব্দার্থবিজ্ঞানের সাথে থাকা ভাল।
ব্রুস এডিগার

9
অথবা এই সমাধানে এর পাইথন পথ, মোড়ানো তোমাদের ইচ্ছার বিরুদ্ধেই চাপিয়ে হবে যা aএবং bমধ্যে str(a)এবং str(b)কল; অন্যথায়, আপনি একটি পেতে ValueError: cannot concatenate 'str' and 'int'
অ্যাফেক্স

6
@ ফ্রাস্ট্রেটেড উইথফোর্ডস ডিজাইনার: প্রথম বন্ধনী যুক্ত করুন। 'result is ' + (a + b)
জন পুরি

18
কথাটি হচ্ছে, সি # তে আপনি একই জিনিসটি করতে পারতেন এবং আপনি একই ফলাফল পাবেন - System.Console.WriteLine("result is " + 10 + 20);তবে সি # তে কেউ কখনও অভিযোগ করে না। এটিই আমি বুঝতে পারি না - জাভাস্ক্রিপ্ট সম্পর্কে এটি কী এটি আরও বিভ্রান্তিকর করে তোলে?
Configurator

7
@ কনফিগ্রেটর: কারণ মানুষকে বলা হয় সি # নিখুঁত এবং জাভাস্ক্রিপ্ট ভয়াবহ। এগুলি উভয়ই ভুল, তবে একটি ভাষার খ্যাতি লেগেছে বলে মনে হয়, উপলব্ধিগুলি অনেক হিসাবে বিবেচিত হয়, বিশেষত ইন্টারনেটগুলিতে।
gbjbaanb

43

আপনি যখন "খারাপ" বলছেন তখন আপনার অর্থ "ভুল" বা আপনি "ধীর" মানে? গাণিতিক অপারেটর ব্যবহার করে স্ট্রিং সংযুক্তকরণের করতে সম্পর্কে যুক্তি তর্কসাপেক্ষে একটি "ভুল" যুক্তি, কিন্তু এছাড়াও একটি যুক্তি হল যে ব্যবহার করা হচ্ছে +না অনেক স্ট্রিং সংযুক্তকরণের খুব ধীর হতে পারে।

আমরা "Hello" + numberযখন পারফরম্যান্সের বিষয়ে কথা বলি তখন আমরা সেই বিষয়ে কথা বলি না, আমরা বারবার লুপে এটি যুক্ত করে তুলনামূলকভাবে বড় স্ট্রিং তৈরির কথা বলছি।

var combined = "";
for (var i = 0; i < 1000000; i++) {
    combined = combined + "hello ";
}

জাভাস্ক্রিপ্টে (এবং সি # এই বিষয়টির জন্য) স্ট্রিং অপরিবর্তনীয়। এগুলি কখনই পরিবর্তন করা যাবে না, কেবল অন্য স্ট্রিং দিয়ে প্রতিস্থাপন করা হবে। আপনি সম্ভবত সচেতন হন যে combined + "hello "সরাসরি combinedচলকটি সংশোধন করে না - ক্রিয়াকলাপটি একটি নতুন স্ট্রিং তৈরি করে যা দুটি স্ট্রিংকে একসাথে যুক্ত করার ফলস্বরূপ, তবে আপনি combinedযদি পরিবর্তন করতে চান তবে আপনাকে অবশ্যই সেই নতুন স্ট্রিংটি ভেরিয়েবলের কাছে বরাদ্দ করতে হবে।

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

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

var parts = [];
for (var i = 0; i < 1000000; i++) {
    parts.push("hello");
}
var combined = parts.join(" ");

3
এটি একটি দুর্দান্ত উত্তর। এটি কেবল প্রশ্নের উত্তর দেয়নি তবে এটি শিক্ষিতও ছিল।
চার্লস স্প্রেবেরি

3
এটি যদিও আমি আদৌ বোঝাতে চাইছি তা নয়, এটি পুরোপুরি প্রশ্নের সাথে সম্পর্কিত নয়।
কনফিগারকারী

4
দুঃখিত। দেখে মনে হচ্ছে কমপক্ষে 7 জন আপনার প্রশ্নটি যেভাবে বলা হয়েছিল তা থেকে ভুল বোঝে।
জোয়েল মুলার

9
পারফরম্যান্স: সম্ভবত ২০১১ সালে এটি হয়েছিল তবে এখন + অপারেটর পদ্ধতি অ্যারে.জয়িন পদ্ধতির তুলনায় অনেক দ্রুত (কমপক্ষে v8) is এই jsperf দেখুন: jsperf.com/string-concateation101
আপ

2
যোগদানের পদ্ধতিটি কীভাবে এক ধাপে একাধিক অংশের মধ্যে একটি স্ট্রিং উত্পন্ন করে তার পরিবর্তে একে একে একে একত্রিত করার পরিবর্তে, এই জাতীয় সমস্ত মধ্যবর্তী স্ট্রিং তৈরি করে কীভাবে ধারণা?
অ্যাঞ্জেলো.হান্নেস

14

যতক্ষণ আপনি কেবল সংখ্যার যোগ করতে পারবেন এবং কেবল সংক্ষিপ্ত স্ট্রিং থাকতে পারে উভয়ই সংযোজন এবং সংক্ষেপণের জন্য + ব্যবহার করা খারাপ নয়। যাইহোক, জাভাস্ক্রিপ্ট প্রয়োজন অনুযায়ী স্বয়ংক্রিয়ভাবে সংখ্যা এবং স্ট্রিংয়ের মধ্যে রূপান্তর করবে, সুতরাং আপনার কাছে:

3 * 5 => 15
"3" * "5" => 15
2 + " fish" => "2 fish"
"3" + "5" => "35"  // hmmm...

সম্ভবত আরও সহজভাবে, স্বয়ংক্রিয় ধরণের রূপান্তরটির উপস্থিতিতে "+" ওভারলোডিং + অপারেটরের প্রত্যাশিত সাহচর্যকে ভেঙে দেয়:

("x" + 1) + 3 != "x" + (1 + 3)

2
সংযোজন থেকে অতিরিক্ত 3 + 5 == 5 + 3"3" + "5" != "5" + "3"
সংযোজনমূলক

10

স্ট্রিং কনটেন্টেশনের জন্য উত্থাপিত সাধারণ সমস্যাটি কয়েকটি ইস্যুতে ঘুরে দেখা যায়:

  1. +প্রতীক ওভারলোড হচ্ছে
  2. সাধারণ ভুল
  3. প্রোগ্রামাররা অলস হচ্ছে

# 1

+স্ট্রিং কনটেনটেশন এবং সংযোজনের জন্য ব্যবহারের সাথে প্রথম এবং সর্বাগ্রে সমস্যা হ'ল আপনি +স্ট্রিং সংমিশ্রণ এবং সংযোজনের জন্য ব্যবহার করছেন ।

আপনার যদি ভেরিয়েবল থাকে aএবং bএবং আপনি সেট c = a + bকরেন তবে aএবং এর ধরণের উপর নির্ভর করে একটি অস্পষ্টতা রয়েছে b। এই অস্পষ্টতা সমস্যাটি প্রশমিত করতে আপনাকে অতিরিক্ত পদক্ষেপ নিতে বাধ্য করে:

স্ট্রিং কনক্যাট:

c = '' + a + b;

সংযোজন:

c = parseFloat(a) + parseFloat(b);

এটি আমার দ্বিতীয় পয়েন্টে নিয়ে আসে

# 2

স্ট্রিংয়ের বিষয়টি উপলব্ধি না করে ঘটনাক্রমে কোনও পরিবর্তনশীল castালাই খুব সহজ। আপনার ইনপুটটি স্ট্রিং হিসাবে চলে আসছে তা ভুলে যাওয়াও সহজ:

a = prompt('Pick a number');
b = prompt('Pick a second number');
alert( a + b );

অনিয়মিত ফলাফল আনবে কারণ প্রম্পট ইনপুটটির স্ট্রিং মান দেয় returns

# 3

টাইপ করার প্রয়োজন parseFloatবা Number()প্রতিবার আমি সংযোজন করতে চাই ক্লান্তিকর এবং বিরক্তিকর। আমি আমার গতিশীল প্রকারগুলি গোলযোগ না করার জন্য নিজেকে যথেষ্ট স্মার্ট মনে করি, তবে এর অর্থ এই নয় যে আমি কখনই আমার গতিশীল প্রকারগুলিকে গোলমাল করি না । বিষয়টির সত্যতা হ'ল আমি টাইপ করতে খুব অলস parseFloatবা Number()প্রতিবার আমি সংযোজন করি কারণ আমি প্রচুর সংযোজন করি।

সমাধান?

সমস্ত ভাষাগুলি +স্ট্রিং কনটেনটেশনের জন্য ব্যবহার করে না । পিএইচপি .স্ট্রিংগুলিকে সংযুক্ত করতে ব্যবহার করে, যা আপনি কখন সংখ্যাগুলি যুক্ত করতে চান এবং আপনি যখন স্ট্রিংগুলিতে যোগদান করতে চান তার মধ্যে পার্থক্য করতে সহায়তা করে।

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

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