Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Странное поведение Boolean (http://www.flasher.ru/forum/showthread.php?t=214022)

Bletraut 28.03.2017 18:17

Странное поведение Boolean
 
Почему не работает

Код AS3:

trace(true * 2); //Error: Implicit coercion of a value of type Boolean to an unrelated type Number.

Однако, исправно работает

Код AS3:

trace(true + 2); // 3

В джаве, например, не работает ни одна из конструкций. В питоне работают обе, но в ас3 только одна, почему?

Tails 28.03.2017 19:03

Лучше всегда избегать неявного преобразования типов по разным соображениям. (Качество и безопасность кода, скорость выполнения.)

Wolsh 28.03.2017 20:27

"+" — более сложный генерик, допускающий разнообразие типов, например при сложении строк. Умножение строк допустимо? )))

Bletraut 29.03.2017 00:47

Цитата:

Сообщение от Wolsh (Сообщение 1199898)
"+" — более сложный генерик, допускающий разнообразие типов, например при сложении строк. Умножение строк допустимо? )))

Почему тогда в джаве не работает?

Добавлено через 36 секунд
Да и к тому же получается на 12 как если бы мы складывали строки, а число 3.

СлаваRa 29.03.2017 10:13

Код:

Почему тогда в джаве не работает?
Чтобы вам еще интереснее было

в CLisp-e (+ t 2) +: T is not a number, ( * t 2) : T is not a numbe
в python True * 2 == 2, True + 2 == 3
в js true * 2 == 2 и true + 2 == 3
Erlang
3> true + 2.
** exception error: an error occurred when evaluating an arithmetic expression
in operator +/2
called as true + 2
4> true * 2.
** exception error: an error occurred when evaluating an arithmetic expression
in operator */2
called as true * 2
в haxe - не скомпилирует
c++11 true * 2 == 2, true + 2 == 3
c# - не скомпилируется
rust - не скомпилируется

UPD
Код:

Bash

$ echo $((TRUE+2))
2
$ echo $((TRUE*2))
0


Bletraut 29.03.2017 16:03

Цитата:

Сообщение от СлаваRa (Сообщение 1199906)
Код:

Почему тогда в джаве не работает?
Чтобы вам еще интереснее было

в CLisp-e (+ t 2) +: T is not a number, ( * t 2) : T is not a numbe
в python True * 2 == 2, True + 2 == 3
в js true * 2 == 2 и true + 2 == 3
Erlang
3> true + 2.
** exception error: an error occurred when evaluating an arithmetic expression
in operator +/2
called as true + 2
4> true * 2.
** exception error: an error occurred when evaluating an arithmetic expression
in operator */2
called as true * 2
в haxe - не скомпилирует
c++11 true * 2 == 2, true + 2 == 3
c# - не скомпилируется
rust - не скомпилируется

UPD
Код:

Bash

$ echo $((TRUE+2))
2
$ echo $((TRUE*2))
0


А я о чём и говорю, что в строготипизированных языках не работает как + так и *. Однако, в ас3 работает +.

СлаваRa 29.03.2017 16:16

Цитата:

А я о чём и говорю, что в строготипизированных языках не работает как + так и *. Однако, в ас3 работает +.
c++ строготипизированный язык?

ЗЫ
Зачем работая с as3 вы сравниваете что-то с другими языками, когда вы с ними в данный момент не работаете? почитайте про приведение типов в ас3, посмотрите на оператор +, подумайте, все встанет на свои места

callme 29.03.2017 17:20

СлаваRa, ну что вы в загадки то играете. Лучше объясните по какой логике разработчики языка разрешили неявное приведение булева типа к числу для сложения, но не разрешили для умножения. Уверен можно уложиться в одно предложение.

СлаваRa 29.03.2017 17:50

оператор + перегружен(на уровне VM), как минимум, для конкатенации строк, скорее всего(уверен в этом на 146%), приведение типа срабатывает в зависимости от каких-то условий, т.е. при использовании + для конкатенации? происходит преобразование в строку, если один из операндов строка, видимо при использовании операции сложения bool и int первый из-за автокаста преобразуется в ближайшее подходящее, т.е. в int(1), оператор * используется только для умножения числовых типов и не имеет иных предназначений, поэтому никаких преобразований операндов не происходит.

Bletraut 29.03.2017 18:31

Код AS3:

trace(true + false); // 1
trace(true + "abc"); // trueabs
trace(true + 2 + "abc"); // 3abc

Добавлено через 6 минут
Цитата:

Сообщение от СлаваRa (Сообщение 1199920)
оператор + перегружен(на уровне VM), как минимум, для конкатенации строк, скорее всего(уверен в этом на 146%), приведение типа срабатывает в зависимости от каких-то условий, т.е. при использовании + для конкатенации? происходит преобразование в строку, если один из операндов строка, видимо при использовании операции сложения bool и int первый из-за автокаста преобразуется в ближайшее подходящее, т.е. в int(1), оператор * используется только для умножения числовых типов и не имеет иных предназначений, поэтому никаких преобразований операндов не происходит.

А в той же джаве разве оператор + не перегружен?

СлаваRa 29.03.2017 18:40

причем тут Java, какое она имеет отношение к AS3?

callme 29.03.2017 18:42

СлаваRa, это всё понятно, но мне кажется такое поведение языка непоследовательным. Надо было разрешить неявное приведение булева типа к числу и в других операциях.

Bletraut 29.03.2017 18:42

В приведение типов про оператор + ничего не сказано, чтобы позволяло ему складывать логические переменные.

Добавлено через 42 секунды
Цитата:

Сообщение от СлаваRa (Сообщение 1199924)
причем тут Java, какое она имеет отношение к AS3?

Такое что + там тоже перегружен, однако, сложить true и 2 нельзя.

Добавлено через 3 минуты
Могли бы в других операторах разрешить приведение типов, а не только в +.

Добавлено через 10 минут
Тем более оператором +, нельзя выполнить математическое сложение числа и строки с числом, всегда будет строка.

Добавлено через 13 минут
Код AS3:

В приведение типов про оператор + ничего не сказано, чтобы позволяло ему складывать логические переменные.

Точнее там сказано, что если выражение не является строкой, то флеш плеер его автоматически преобразует в число. Что им мешало сделать тоже самое с остальными?

caseyryan 29.03.2017 20:42

Цитата:

Такое что + там тоже перегружен, однако, сложить true и 2 нельзя.
И тем не менее, я тоже не понимаю, при чем тут джава? Другой язык, другая платформа, другие разработчики. Там и строка не является примитивным типом и с помощью == строки не сравниваются посимвольно как в as3, вместо этого используется метод equals. И много других отличий. Не вижу смысла искать одинаковое поведение операторов в языках, в которых и без этого миллион различий.
Цитата:

Могли бы в других операторах разрешить приведение типов, а не только в +.
Для чего?
Не вижу ни одной ситуации, где это бы пригодилось. Возможно не хватает перегрузки операторов, например, чтобы упростить сложение векторов. Но умножать булево на число - занятие совершенно бессмысленное. Если уж это для чего-то потребовалось, ты всегда можешь сделать явное приведение типов и без проблем произвести операцию

Жень Шень 30.03.2017 13:33

Мне кажет, что каша в голове по поводу "странного поведения Boolean" возникла из-за двойственного предназначении оператора +, а именно:
+ addition
Складывает числовые выражения. Если оба выражения являются целыми числами, их сумма также будет выражена целым числом; если одно из выражений или оба выражения являются числами с плавающей запятой, их сумма также будет выражена числом с плавающей запятой.
Если одно выражение является строкой, все другие выражения преобразуются в строки и сцепляются, а не суммируются. В противном случае, если выражение не является числом, проигрыватель Flash® Player преобразует его в число.

+ concatenation
Сцепляет (объединяет) строки. Если одно выражение является строкой, все другие выражения преобразуются в строки и сцепляются.
Если оба выражения являются числами, данный оператор выполняет функцию оператора сложения.
Компилятор распознаёт, что вы имели ввиду в своём выражении.
А теперь посмотрим, что будет, если приведение логики будет с другими операторами:
123/false = 123/0 – деление на ноль;
true * "one" – умножение строк. А это как?
Ну и дальше в том же духе.

Bletraut 30.03.2017 19:23

Цитата:

Для чего?
Не вижу ни одной ситуации, где это бы пригодилось.
Понадобилось мне для игры, где в зависимости от значения к итоговому значению переменной прибавляется некоторое число, и чтобы не городить условий я просто написал.

Код AS3:

a = 20;
b = 80;
c = true;
d = a + c*b;


Wolsh 30.03.2017 20:34

Код AS3:

d = c ? a + b : a;


caseyryan 31.03.2017 10:20

Цитата:

Сообщение от Bletraut (Сообщение 1199956)
Понадобилось мне для игры, где в зависимости от значения к итоговому значению переменной прибавляется некоторое число, и чтобы не городить условий я просто написал.

Код AS3:

a = 20;
b = 80;
c = true;
d = a + c*b;


Вот я я и говорю, для таких редких случаев, можно сделать явное приведение типа

Bletraut 31.03.2017 16:05

Цитата:

Сообщение от Wolsh (Сообщение 1199959)
Код AS3:

d = c ? a + b : a;


Удобочитаемость страдает.

СлаваRa 31.03.2017 19:52

Код AS3:

d = a + int(c)*b;


Bletraut 31.03.2017 20:47

Цитата:

Сообщение от СлаваRa (Сообщение 1199973)
Код AS3:

d = a + int(c)*b;


Собственно я так и сделал, просто думал вдруг есть вариант без явного приведения.

KBAC 31.03.2017 23:12

d = c ? a + b : a;

Читается как "d равно если с, то a плюс b, иначе а"

d = a + int(c)*b;
Читается как "d равно a плюс результат приведения с к инту умноженный на b"

И где теряется читаемость?

Bletraut 01.04.2017 01:03

Цитата:

Сообщение от KBAC (Сообщение 1199979)
d = c ? a + b : a;

Читается как "d равно если с, то a плюс b, иначе а"

d = a + int(c)*b;
Читается как "d равно a плюс результат приведения с к инту умноженный на b"

И где теряется читаемость?

Удобочитаемость это больше визуальное восприятие.

Например гораздо легче прочитать:

Код AS3:

function getNames(i:int):String
{
    switch(i)
    {
        case 1:
            return "John";
        break;
        case 2:
            return "Em";
        break;
        case 3:
            return "Martin";
        break;
        default:
            return "Cock";
        break;
    }
}

или

Код AS3:

function getNames(i:int):String
{
    var names:Array = ["John", "Em", "Martin"];
    var defName:String = "Cock";
 
    return (i < names.length) ? names[i] : defName;
}

Чем:
Код AS3:

function getNames(i:int):String { return (i == 1) ? "John" : (i == 2) ? "Em" : (i == 3) ? "Martin" : "Cock"; }


СлаваRa 01.04.2017 01:06

развейте ваш switch до 500 кейсов

callme 01.04.2017 11:06

Красивый пример умножения числа на булево:
Код AS3:

зарплата = оклад
    + квартальнаяПремия * положенаКвартальнаяПремия
    + премияЛучшемуМенеджеру * лучшийМенеджер
    + премияПьющимМолоко * пьетМолоко;



Часовой пояс GMT +4, время: 10:50.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.