Proč operátor && vyrábět typ druhého operandu

hlasů
24

Specifikaci strojopisem státy v §4.15.6 o &&provozovateli:

Operátor && dovoluje operandy být jakéhokoliv typu, a produkuje výsledky stejného typu jako druhý operand .

V JavaScriptu se &&vrátí operátor první operand, pokud je falsy, jinak vrací druhý operand ( viz ECMA-262 §11.11 ).

To znamená, že v případě, že levý operand je falsy, &&vrátí hodnotu, která odpovídá typu levý operand. Například,

typeof ( false && {}      ) === boolean // true
typeof ( ''    && 1       ) === string  // true
typeof ( null  && hello ) === object  // true
typeof ( NaN   && true    ) === number  // true

Strojopisem, podle pravidla výše citované by nesprávně předpovědět typy výše uvedených výrazů jako Object, Number, Stringa Boolean, v uvedeném pořadí.

Uniká mi něco? Je tu dobrý důvod, aby se druh z &&výrazu odpovídal typu druhý operand? Neměl by druh výsledku chová jako ||operátor, a vrátit nejlepší společný typ dvěma operandy, a Anynení-li nejlepší běžný typ?

Položena 02/10/2012 v 16:50
zdroj uživatelem
V jiných jazycích...                            


1 odpovědí

hlasů
20

Dlouhý příběh krátký, není zde žádná řešení, které potěší každého.

Vezměme si tento společný idiom:

var customer = GetCustomer(...); // of type 'Customer'
var address = customer && customer.address;
if(address) {
    printAddressLabel(address); // Signature: (Address) => void
} else {
    // Couldn't find the customer or the customer has no address on file
}

To by bylo docela lame vzdát a rozhodne, že ‚adresa‘ je ‚každý‘, protože neexistuje žádný nejlepší běžný typ mezi zákazníkem a adresy.

Ve většině případů, kdy je použit operátor && buď typy již neodpovídají, nebo && je používán způsobem hodnoty splývání jako výše. V obou případech vrací typ pravého operandu dává uživateli očekávaný typ.

Zatímco bezpečnostní typ je technicky poškodí v tomto bodě, je to, proč tak nečiní způsobem, který je pravděpodobně za následek chybu. Buď budete testovat výslednou hodnotu truthiness (v tomto případě se jedná o typ víceméně irelevantní), nebo se chystáte použít pravděpodobnou pravý operand pro některé operace (výše uvedený příklad dělá obojí).

Podíváme-li se na příklady, které jste uvedli, a předstírat, že levý operand je neurčitě truthy nebo falsy a zkuste psát zdravou kód, který bude fungovat na návratovou hodnotu, to se stává mnohem přehlednější - je tam prostě není moc, můžete dělat s ‚false && {}‘, který není již jít do" jakoukoliv argument poloze nebo truthiness testu.


dodatky

Vzhledem k tomu, že někteří lidé nebyli přesvědčeni o výše uvedené, tady je jiná vysvětlení.

Pojďme předstírat, že na chvíli, že typ strojopis systém zvýšené o tři nové druhy: Truthy<T>, Falsy<T>, a Maybe<T>, což představuje možné truthy / falsy hodnoty typu T. Pravidla pro tyto typy jsou následující:

  1. Truthy<T> se chová přesně jako T
  2. Nelze získat přístup k žádné vlastnosti Falsy<T>
  3. Výraz typu Maybe<T>, pokud je použit jako podmínka v ifbloku, se stává Truthy<T>v těle téhož ifbloku a Falsy<T>v elsebloku

To by vám umožní dělat věci, jako je tento:

function fn(x: Maybe<Customer>) {
   if(x) {
      console.log(x.address); // OK
   } else {
      console.log(x.phone); // Error: x is definitely falsy
   }
   console.log(x.name); // Warning: x might be falsy!
}

Docela dobře tak daleko. Nyní můžeme zjistit, jaká jsou pravidla typu jsou pro provozovatele &&.

  • Truthy<T> && x by měla být chyba - je-li levé straně je známo, že truthy, měli byste právě psaný x
  • Falsy<T> && xby měla být chyba - je-li levé straně je známo, že falsy, xje nedosažitelný kód
  • Maybe<T> && x by měl produkovat ... co?

Víme, že výsledkem Maybe<T> && xbude buď falsy hodnota typu T, nebo x. To nemůže produkovat Truthy<T>(pokud T== typ xv takovém případě celá tato diskuse je diskutabilní). Nazvěme tento nový typ Falsy<T> XOR Maybe<U>.

Co by měla pravidla Falsy<T> XOR Maybe<U>být?

  • Je jasné, že nelze použít vlastnosti Tna něm. Pokud je hodnota typu T, je to falsy a není bezpečné pro použití.
  • Byste měli být schopni používat to jako Maybe<U>, protože Falsy<T>a Falsy<U>mají stejné chování
  • Neměli byste být schopni používat vlastnosti U, protože hodnota stále může být falsy.
  • Pokud jej používáte v iftestu, pak by měl stát Truthy<U>v bloku tohoto ifprohlášení

Jinými slovy, Falsy<T> XOR Maybe<U> je Maybe<U> . Z toho vyplývá, všechny stejná pravidla. Nemusíte komplikovat systém typů vůbec tady přidáním takový divný XORtyp, protože typ, který je vhodný pro všechny specifikace, které potřebujete již existuje.

To je trochu jako dávat někomu krabici a říká: „To je buď prázdný box odpadků, nebo plné krabice recyklovatelných“. Můžete bezpečně vyprázdnit obsah krabice do recyklačního kontejneru.

Odpovězeno 02/10/2012 v 17:55
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more