Rust: كلمة var لسكان محليين قابلين للتغيير فقط

تم إنشاؤها على ٢٠ يونيو ٢٠١٢  ·  35تعليقات  ·  مصدر: rust-lang/rust

اقترحت المشكلة رقم 1273 let mut للسكان المحليين القابل للتغيير و mut للحقول القابلة للتغيير. let mut مطول أكثر من كلمة رئيسية واحدة كما أنه يقطع محاذاة الأعمدة. لم يعجب الناس حقًا بفكرة var لإعلانات الحقول القابلة للتغيير. لكنني أعتقد أنه لم يقترح أحد فكرة استخدام var للإعلانات المحلية القابلة للتغيير و mut للإعلانات الميدانية القابلة للتغيير:

let x = 7; // declaration of immutable variable x
var y = 7; // declaration of mutable variable y
type point = { mut x: int, mut y: int }; // declaration of mutable record type

ديف

I-nominated

ال 35 كومينتر

يجب أن أعترف ، لقد اعتقدت في البداية أنه يجب علينا استخدام نفس الكلمة الرئيسية للمتغيرات القابلة للتغيير والحقول القابلة للتغيير ، لكن var يقرأ جيدًا نوعًا ما (على الرغم من أنني لا أكره let mut )

أعتقد أنها ميزة أن إعلان متغير قابل للتغيير يكون دائمًا أكثر تعقيدًا من متغير غير قابل للتغيير. يمكنني رؤية المبرمجين الذين يستخدمون "var" فقط ليكونوا "متسقين" أو لأن "var" سيكون أكثر قوة (لا يتعين عليك تغييره إذا قررت التغيير لاحقًا). ثم ينتهي بك الأمر برمز أقل قابلية للقراءة بشكل عام.

لا يقترح أن يكون Rust لغة عبودية وانضباط جادة ، ولكن الدفع اللطيف في الاتجاه الصحيح له ما يبرره أخلاقياً ، على ما أعتقد (أي أن القاعدة ستكون "من أجل كود آمن ، يجب أن تكون التركيبات الأكثر أمانًا أقل ضوضاءً من الأقوى ولكن بنيات سهلة الفوضى ").

من ناحية ، أحب هذا ، لأنه سيزيل الغموض البصري من هذا النموذج:

let mut x = 4,
    y = 8;  // is y mutable or not?

لكنني أميل إلى الوقوف مع سيلفان. لا يجب أن يكون إعلان المتغيرات "قبيحًا" تمامًا ، لكنني أعتقد أنه من المنطقي أن تكون أقل ملاءمة لإنشاء العناصر الثابتة ، حتى ولو بضغطة زر واحدة. يجب أيضًا أن تكون الكلمة الأساسية التنشيطية مميزة ، ويتم استخدام (IMO) var على نطاق واسع ككلمة أساسية عامة لإعلان المتغير لنقل قابلية التغيير على وجه التحديد في لغة تفتخر بالثبات افتراضيًا. وفكر في مبرمجي C # الفقراء ، الذين يمثل var بالنسبة إليهم let !

ما زلت أحب فكرة استبدال let mut بكلمة رئيسية واحدة ، وذلك لمعالجة مقتطف الشفرة أعلاه ، ولكن هل هناك أي سبب لإدخال كلمة رئيسية جديدة عندما يكون mut نفسه كافياً ، حسب الاقتراح الأصلي في # 1273؟

أشار pcwalton إلى مشكلة في استخدام mut : هناك غموض في حرفية التسجيلات وتعبيرات الكتلة التي تتطلب نظرة تعسفية إلى الأمام لحلها.

{ mut x: int ...

سجل حرفية ، أو كتلة مع متغير محلي؟

استطعت أن أرى الكثير من المبرمجين يتعلمون للتو أن var هو كيفية تعريفك للمتغيرات في Rust ، وعدم استخدام let على الإطلاق. بعد كل شيء ، var هي الطريقة التي تحدد بها المتغيرات المحلية بلغات مثل JavaScript. أنا أميل إلى الاعتقاد بأن هذا أمر جيد بخصوص هذا الاقتراح.

سمعت شخصًا ما يشير بالأمس إلى أن الآن let و var سيكون لهما نفس الطول ، مما سيكون أمرًا رائعًا للمحاذاة.

أنا غير مبال إلى حد ما ، لكنني أفضل نوعًا ما var ، لأنه أقصر. جعل التغيير مزعجًا ليس هدفًا مرغوبًا كما أراه. (في الواقع ، أنا أميل إلى الاعتقاد بأن دور لغة البرمجة لا ينبغي أن يكون إحداث أي شيء مزعج - فقط _ واضح_ ، وهذا ليس نفس الشيء.)

على الرغم من أنني ما زلت حذرًا من استخدام let و var معًا (تمامًا مثل Javascript ، ولكن مختلفة بنسبة 100٪) ، إلا أنها ستكون مشكلة أقل بكثير إذا كان هناك تمرير من الوبر لاكتشاف المتغيرات التي تم إعلان أنها قابلة للتغيير ولكنها لم تتغير أبدًا.

هناك خطة لجعل قابلية التغيير جزءًا من هذا النوع. هل يؤثر ذلك على السكان المحليين ويجعل ذلك غير ذي صلة؟

ماذا عن:

val x = ... // immutable (val-ue)
var y = ... // mutable (var-iable)

كما هو الحال في سكالا.

أعتقد أن brson محق وتختفي هذه المشكلة بمجرد نقلنا mut إلى أحد الأنواع ، أي تحصل على let x = mut 10;

إغلاق هذه القضية الآن ؛ أعد الفتح إذا كنت تعتقد أنني مخطئ!

لست متأكدا من هذا. تعجبني فكرة نقل mut إلى النوع ، لكنني لا أعرف أنها "صفقة منتهية" - قد يكون هناك غرابة باقية هناك. على أي حال ، لم أفكر أبدًا في أنه قد يكتب أحدهم let x = mut 5 ، لقد افترضت دائمًا أنك ستكتب let mut x = 5 تمامًا كما هو الحال اليوم ؛ تأتي "قابلية التغيير" لنوع المتغير من طريقة الإعلان عنه ، وليس القيمة التي يتم تخصيصها له.

القيام بخلاف ذلك يعني أنه إذا كان لديك مصفوفة x من النوع [mut int] وتكتب let y = x[0] فإن y قابل للتغيير؟ أو شيء ما؟ هذا يبدو غير مرغوب فيه.

Dretch لا أحب val / var لأنها ليست مميزة بما يكفي ، على الرغم من أن سابقة Scala لطيفة.

أشارك eholk قلقهم بشأن تعلم الأشخاص استخدام var افتراضيًا. الطريقة التي تعمل بها الآن أميل إلى إعلان كل شيء على أنه غير قابل للتغيير ، ثم يذكرني المترجم أنه يجب أن يكون قابلاً للتغيير ، ثم أكتب mut . يمكن القول إن هذا سلوك جيد قد تكون أقل ميلًا إليه عند تقسيم var/let - كتابة var و let صعبة بنفس القدر ولكن لا يمكنك حتى كتابة let mut بدون كتابة let .

لكنني لا أملك تفضيلًا وأنا أقدر حقًا عندما يمكنني تكوين وظائف بالكامل من العبارات التي تبدأ بكلمات رئيسية مكونة من ثلاثة أحرف.

nikomatsakis على وجه الخصوص ، من المنطقي بالنسبة لي أن القواعد المتعلقة

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

ديف

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

لا يقتصر التصميم النحوي الجيد لـ IMHO على جعل "كل شيء" قد ترغب في القيام به مناسبًا ، بل يتعلق بدفع الأشخاص بلطف إلى "المسار السلس" لدلالات اللغة وأهداف التصميم.

على سبيل المثال ، ربما لن تضيف دعمًا نحويًا خاصًا للقوائم المرتبطة في Rust (a la Haskell) ، لأن أحد المبادئ الأساسية لـ Rust هو أن تكون فعالًا ، وسيعمل الاستخدام الواسع للقوائم المرتبطة بشكل مخالف لهذا المبدأ. للسبب نفسه ، لا ينبغي أن تكون مشاركة البيانات القابلة للتغيير بين الخيوط مريحة للغاية (نظرًا لأن التزامن الآمن هو مبدأ آخر) ، ولا ينبغي أن يكون من الملائم للغاية إلقاء كلمة تعسفية على مؤشر (نظرًا لأن سلامة الذاكرة هي مبدأ كبير).

كي لا نقول أنه يجب أن يكون من المستحيل القيام بأي من هذه الأشياء ، العقل ، فقط غير مريح نسبيًا بحيث يكون واضحًا من النحو الذي هو الطريقة الاصطلاحية لكتابة Rust.

المتغيرات القابلة للتغيير (المحلية) ليست سيئة مثل أي من هذه المتغيرات ، ولكن إذا كان Rust يفضل بالفعل البيانات غير القابلة للتغيير لأسباب تتعلق بالصحة والصيانة (وهو شيء أتفق معه شخصيًا) ، فيجب أن يعطي بناء الجملة بشكل مثالي دفعة لطيفة في هذا الاتجاه. حتى الحرف الإضافي الفردي أو المُعدِّل الإضافي sigil أو أي شيء سيكون كافيًا لتوضيح أن "let" أقل تعقيدًا من "let mut" أو "let!" أو أيًا كان ، وبالتالي يجب أن يكون الخيار الافتراضي المفضل الذي يجب أن تحاول اتباعه عندما لا تحتاج في الواقع إلى أن يكون المتغير قابلاً للتغيير.

ssylvan أوه ، أنا أفهم هذه النقطة ، إنها مجرد مسألة درجة ، وتوازن المقايضات. نحن نشجع بالفعل ثبات هياكل البيانات ، كما أن الترويج للمواطنين الثابتين في IMO أقل أهمية من الحقول غير القابلة للتغيير. (خاصةً منذ ذلك الحين ، IINM ، لا نسمح للسكان المحليين المتغيرين بالهروب في عمليات إغلاق الكومة.) وفقدان القدرة على إعادة البناء بين let و var دون تغيير عدد الأعمدة يفوق فائدة الترويج لسكان محليين غير قابلين للتغيير. من الصعب تحديده كميًا ، لذلك أعتقد أنه مجرد شعوري.

ديف

حسنًا في هذه الحالة على الأقل "let foo = mut bar" أو "let foo: = bar" بدلاً من "let mut foo = bar" سيجعل الرمز المميز الأول يصطف. من المفترض أن يكون اسم المتغير متغير الطول ، لذا ليس من المهم جدًا تجنب المعدلات الإضافية في بقية العبارة.

أوه ، أنا متحيز نوعاً ما لفكرة := .

ديف

في الفكر الثاني ، باسكال غير بارد بشكل دائم. أنا أستعيدها. :)

ديف

أيضًا ، let foo := bar يمنع شيئًا كهذا:

let mut foo;
foo = bar;

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

eholk لا أعتقد أنه يمنع ذلك. لكن ما زلت أعتقد أنه سيبدو غريبًا جدًا بالنسبة للمبرمجين من أي لغة سائدة تقريبًا.

ديف

فيما يتعلق := ، يستخدمه Go للإشارة إلى مهمة الكتابة الاستدلالية (على الرغم من أنها ليست لغة سائدة تمامًا حتى الآن). لكن يمكنني توقع صعوبة التمييز بين الشكلين في لمحة:

let foo = "hello";
let foo := "hell";

حجة برسون للصيغة الحالية (أي أن التصريح القابل للتغيير يتطلب أولاً التصريح غير القابل للتغيير) مقنع. إنه لأمر رائع تمامًا إذا كانت لغات البرمجة لها رأي ، طالما أنها ليست حمقاء بشأن ذلك. :)

لست مهتمًا بـ = مقابل := . في الغالب يعارضون val و var وأشكال مختلفة منها ؛ إنه ببساطة ليس _ واضحًا_ أنه يتحكم في قابلية التغيير. أعني ، لن أتخلى عن ذلك في اشمئزاز إذا تبنينا واحدًا منهم ، لكنني أعتقد أن "الحاجة إلى شرح ذاكري" هي علامة سيئة. أنا بخير أكثر مع:

  • ترك النوع يملي عليه.
  • السماح لـ mut بالعمل بمفرده كمعلن محلي ومطالبة المحلل اللغوي بتأخير الالتزام ببناء التسجيل مقابل التصريح المحلي لرمز إضافي واحد ؛ لا يزال LL (1) يضيف حالة نحوية وسيطة إضافية ، ولا يوجد تراجع إضافي (كلا الطريقتين إلى الأمام صالحة).
  • تركها كـ let mut .

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

(كانت جميع النطاقات قابلة للتغيير في البداية ، ولكن لم يكن لدينا أيضًا التقاط البيئة ، فقط ربط. الآن ليس لدينا أي ارتباط ، فقط التقاط الحسد. Tomayto ، tomahto.)

أعتقد أنه لا يمكن التقاط المتغيرات ضمنيًا الآن.

graydon محق في أنه كان هناك

  • التقاط ضمني "عن طريق النسخ" للمتغيرات المتغيرة في fn@
  • فهم ما هي البيانات القابلة للتغيير وما هو غير مناسب لـ BOOTRUCK

اتضح أن هذا الأخير لم يعد ذا صلة. كان استخدام المتغيرات المتغيرة / غير القابلة للتغيير فظًا جدًا في الممارسة العملية ، لذا فقد كان لدى Bomberck فكرة استعارة متغير "مؤقتًا" --- يمكن استعارة متغير قابل للتغيير باستخدام ptr ثابت طالما لم يتم تعديل المتغير أثناء وجود المؤشر في مجال.

ربما يمكننا إزالة فكرة السكان المحليين القابل للتغيير / غير القابل للتغيير والعودة إلى القاعدة القديمة - كل شيء قابل للتغيير. يمكننا بعد ذلك إصدار تحذيرات عندما يتم تعديل متغير تم نسخه ضمنيًا إلى الإغلاق بعد إنشاء الإغلاق.

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

Dretch أنا أيضًا أحب أسلوب سكالا ، مع الكلمات الرئيسية "فال" و "فار".

أحب كيف يتسبب بناء الجملة الحالي في ظهور المتغيرات مثل إبهام مؤلم ؛ يجعل مسح الشفرة أسهل. val و var متشابهين جدًا في هذا الصدد. وهذا لا يعني أن العناصر المتغيرة _ يجب_ أن تظل ثابتة تمامًا ، ولكن الاحتفاظ بالكلمات الرئيسية مميزة بصريًا يعد جانبًا مهمًا من جوانب سهولة الاستخدام.

أنا أفهم أنه سيتم إزالة الحقول القابلة للتغيير من الصدأ. هل يعني ذلك أنه يمكن استخدام mut بعد ذلك بدلاً من let mut لأن غموض السجل / المتغير في الكتلة سيختفي؟

أعتقد أيضًا أن السجلات الهيكلية مستمرة ، مما يزيل الغموض حتى لو بقيت الحقول القابلة للتغيير.

Dretch صحيح أن الحقول القابلة للتغيير في طريقها للخروج ، وأن السجلات الهيكلية قد اختفت بالفعل.

أنا في الغالب غير مبال بالمشكلة ، على الرغم من أنني أود أن أشير إلى أنه من المنطقي أن يكون mut كلمة رئيسية للإعلان في حد ذاته (كما يقترح Dretch) ، في حالة التجميد / الذوبان . قارن اليوم:

let foo = 1;  // immutable
/* 10,000 lines of code here */
let mut foo = foo;  // we're making foo mutable, totally understandable
/* 10,000 lines of code here */
let foo = foo;  // potential wtf

مع الاقتراح:

let foo = 1;  // immutable
/* 10,000 lines of code here */
mut foo = foo;  // a mutable foo, no problems here
/* 10,000 lines of code here */
let foo = foo;  // slightly less of a potential for wtf, since we officially have two declaration forms

على الرغم من أنني أشعر أيضًا أن هذا من شأنه أن يجعل "عدم وجود طفرات في Rust-ism يعني عدم قابلية التغيير" أقل اتساقًا ، لأننا ما زلنا نكتب let foo = 1; بدلاً من foo = 1; (من الواضح أن الشكل الأخير هو غير مرغوب فيه للإعلان).

تستخدم Kotlin أيضًا val و var .

لا أعتقد أننا سنجري هذا التغيير ، لكنني سأرشح للمعلم 1 ، المحدد جيدًا ، حتى نتمكن من تسويته.

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

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات