هل من الممارسات الجيدة استخدام عامل التشغيل xor لإجراء عمليات التحقق المنطقية؟

StackOverflow https://stackoverflow.com/questions/160697

سؤال

أنا شخصيا أحب حصري أو, ^, ، عامل التشغيل عندما يكون منطقيًا في سياق عمليات التحقق المنطقية بسبب إيجازه.أفضّل الكتابة كثيرًا

if (boolean1 ^ boolean2)
{
  //do it
}

من

if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
  //do it
}

ولكن غالبًا ما أحصل على نظرات مشوشة من مطوري Java الآخرين ذوي الخبرة (وليس فقط المبتدئين)، وأحيانًا تعليقات حول كيفية استخدامها فقط لعمليات البت.

أشعر بالفضول لمعرفة أفضل الممارسات فيما يتعلق باستخدام ملف ^ المشغل أو العامل.

هل كانت مفيدة؟

المحلول

ويمكنك ببساطة استخدام != بدلا من ذلك.

نصائح أخرى

وأعتقد أنك قد أجبت على السؤال الخاص بك - اذا كان لديك نظرات غريبة من الناس، هو على الأرجح أكثر أمنا للذهاب مع خيار أكثر وضوحا

.

إذا كنت بحاجة إلى التعليق عليه، ثم ربما كنت أفضل حالا استبدالها نسخة أكثر مطول ولا يجعل الناس يسألون السؤال في المقام الأول.

وأجد أن لدي محادثات مماثلة كثيرا. من ناحية، لديك أسلوب التعاقد، كفاءة لتحقيق هدفك. من ناحية أخرى، لديك شيء ما قد لا يفهم بقية أعضاء الفريق، مما يجعل من الصعب الحفاظ في المستقبل.

وبلدي القاعدة العامة هي أن نسأل إذا كانت تقنية تستخدم شيء أنه من المعقول أن نتوقع المبرمجين بشكل عام إلى معرفته. في هذه الحالة، أعتقد أنه من المعقول أن نتوقع المبرمجين لمعرفة كيفية استخدام العوامل المنطقية، وذلك باستخدام XOR في بيان إذا ما يرام.

وكمثال على شيء من شأنه أن لا يكون حسنا، واتخاذ خدعة استخدام XOR لمبادلة اثنين من المتغيرات دون استخدام متغير مؤقت. هذا هو الحيلة التي لا اتوقع من الجميع أن يكون على دراية، لذلك لن يمر مراجعة التعليمات البرمجية.

وأعتقد أنه سيكون بخير إذا كنت قد علقت عليه، على سبيل المثال، // ^ == XOR.

هل يمكن دائما مجرد التفاف عليه في وظيفة لإعطائها اسم المطول:

public static boolean XOR(boolean A, boolean B) {
    return A ^ B;
}

ولكن، يبدو لي أنه لن يكون من الصعب على أي شخص لا يعرف ما هو ^ المشغل للجوجل انها حقا سريعة. فإنه لن يكون من الصعب أن نتذكر بعد المرة الأولى. وبما انك طلبت لاستخدامات أخرى، لها شيوعا لاستخدام XOR لإخفاء بعض الشيء.

ويمكنك أيضا استخدام XOR لمبادلة القيم في اثنين من المتغيرات دون استخدام متغير مؤقت الثالث .

// Swap the values in A and B
A ^= B;
B ^= A;
A ^= B;

وفيما يلي ستاكوفيرفلوو سؤال يتعلق XOR مبادلة .

ولقد استخدمت مؤخرا XOR في مشروع جافا سكريبت في العمل و انتهى مضيفا 7 خطوط من التعليقات لشرح ما يجري. وكان المبرر لاستخدام XOR في هذا السياق أن واحدا من الشروط (term1 في المثال أدناه) يمكن أن تحمل وليس اثنين بل ثلاثة القيم: undefined، true أو false في حين أن الآخر (term2) يمكن true أو false. أود أن كان لإضافة الاختيار إضافية لحالات undefined ولكن مع XOR، كان ما يلي كافية منذ XOR قوات الفصل الدراسي الأول التي سيتم تقييمها بوصفها أول منطقية، والسماح undefined الحصول على العلاج كما false:

if (term1 ^ term2) { ...

وكان، في النهاية، وقليلا من مبالغة، ولكني أردت أن يبقيه في هناك على أية حال، كنوع من بيضة عيد الفصح.

if((boolean1 && !boolean2) || (boolean2 && !boolean1)) 
{ 
  //do it 
} 
يمكن تبسيطها

وIMHO هذا الرمز:

if(boolean1 != boolean2) 
{ 
  //do it 
} 

ومع وضوح التعليمات البرمجية في الاعتبار، رأيي هو أن استخدام XOR في الشيكات منطقية ليس الاستخدام العادي للمشغل أحادي المعامل XOR. من واقع خبرتي، أحادي المعامل XOR في جاوة هو عادة استخدامها لتنفيذ السلوك قناع flag toggle:

flags = flags ^ MASK;

هذه المقالة التي كتبها Vipan سينغلا يفسر حالة استخدام المزيد من التفاصيل.

إذا كنت بحاجة إلى استخدام XOR أحادي المعامل كما في المثال الخاص بك، والتعليق لماذا استخدامه، نظرا لأنه من المحتمل أن تحتاج حتى أحادي المعامل جمهور القراءة والكتابة لوقف في مساراتها أن نفهم لماذا تقوم باستخدامه.

إذا كان نمط الاستخدام يبرر ذلك، فلماذا لا؟على الرغم من أن فريقك لا يتعرف على المشغل على الفور، إلا أنه سيتمكن من ذلك مع مرور الوقت.يتعلم البشر كلمات جديدة في كل وقت.لماذا لا في البرمجة؟

التحذير الوحيد الذي يمكنني ذكره هو أن "^" لا يحتوي على دلالات الدائرة القصيرة الخاصة بالفحص المنطقي الثاني.إذا كنت حقًا بحاجة إلى دلالات الدائرة القصيرة، فإن طريقة الاستخدام الثابتة تعمل أيضًا.

public static boolean xor(boolean a, boolean b) {
    return (a && !b) || (b && !a);
}

وأنا شخصيا أفضل "boolean1 ^ boolean2" التعبير بسبب إيجازها بها.

إذا كنت في وضعك (العمل ضمن فريق)، وأود أن توصل الى حل وسط عن طريق التغليف و"boolean1 ^ boolean2" المنطق في وظيفة مع اسم وصفي مثل "isDifferent (boolean1، boolean2)".

وعلى سبيل المثال، بدلا من استخدام "boolean1 ^ boolean2"، يمكن أن أسميه "isDifferent (boolean1، boolean2)" مثل ذلك:

if (isDifferent(boolean1, boolean2))
{
  //do it
}

والخاص بك "isDifferent (boolean1، boolean2)" وظيفة ستبدو:

private boolean isDifferent(boolean1, boolean2)
{
    return boolean1 ^ boolean2;
}

وبطبيعة الحال، ينطوي هذا الحل استخدام استدعاء دالة غريبة في الظاهر، والذي يخضع للتدقيق أفضل الممارسات في حد ذاته، ولكنه يتجنب مطول (والقبيح) التعبير "(boolean1 &&! boolean2) || (boolean2 && ! boolean1) "!

و! = غير موافق للمقارنة بين المتغيرات. أنها لا تعمل، رغم ذلك، مع مقارنات متعددة.

str.contains("!=") ^ str.startsWith("not(")

ويبدو أفضل بالنسبة لي من

str.contains("!=") != str.startsWith("not(")

وكما عامل أحادي المعامل، XOR هو أسرع بكثير من أي وسيلة أخرى ليحل محله. وذلك لأداء النقدي والحسابات قابلة لل، XOR أمر حتمي.

ورأيي الشخصي شخصي: لا يجوز على الاطلاق، ولأي غرض من الأغراض، لاستخدام المساواة (== أو =!) لالقيم المنطقية. باستخدام هذا يظهر عدم وجود الأخلاق البرمجة الأساسية والأسس. أي شخص يمنحك الخلط يبدو أكثر ^ يجب أن ترسل إلى أساسيات الجبر منطقية (الأول كان يميل لكتابة "لأنهار المعتقد" هنا :)).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top