Lhs rhs что это
объясните, пожалуйста, популярно для невежд (если можно — на примерах) что такое в С++ параметр rhs(right-hand side — стоящий справа) чем он отличается, кроме расположения, от lhs, а также в каких случаях его нужно применять и как
спасибо
| От: | Lorenzo_LAMAS |
| Дата: | 16.07.03 09:46 |
| Оценка: |
По-моему, это просто используемое (не обязательно, что всеми) имя формального аргумента в бинарных операторах, какого-то особенного смысла и тонкостей искать не стоит.
Of course, the code must be complete enough to compile and link.
| От: | Dimkin |
| Дата: | 16.07.03 13:19 |
| Оценка: |
Здравствуйте, lightix, Вы писали:
L>объясните, пожалуйста, популярно для невежд (если можно — на примерах) что такое в С++ параметр rhs(right-hand side — стоящий справа) чем он отличается, кроме расположения, от lhs, а также в каких случаях его нужно применять и как
Такого понятия как rhs и lhs в C++ нет! Это просто удобный способ именования параметров в бинарных операторах (по моему его Элджер в своей книжке применяет)! Может быть ты хотел спросить про Lvalue?
| От: | Дюша | http://www.danfoss.com/russia |
| Дата: | 18.07.03 08:31 | |
| Оценка: |
Для того, чтобы понять ето, надо слегка копнуть в теорию компиляторов.
Твоя программа анализируется с помощью правил, типа:
statement : INT_NUM + INT_NUM;//из statement можно получить сумму 2-х чисел
В етом случае «statement» называется Left Hand Side (of the rule) а, «INT_NUM +INT_NUM;» соответственно, Right Hand Side.
Вот, собственно, и всё!
| От: | Дюша | http://www.danfoss.com/russia |
| Дата: | 18.07.03 08:32 | |
| Оценка: |
Для того, чтобы понять ето, надо слегка копнуть в теорию компиляторов.
Твоя программа анализируется с помощью правил, типа:
statement : INT_NUM + INT_NUM;//из statement можно получить сумму 2-х чисел
В етом случае «statement» называется Left Hand Side (of the rule) а, «INT_NUM +INT_NUM;» соответственно, Right Hand Side.
Вот, собственно, и всё!
Вы отправили слишком много запросов, поэтому ваш компьютер был заблокирован.
Для того, чтобы предотвратить автоматическое считывание информации с нашего сервиса, на Linguee допустимо лишь ограниченное количество запросов на каждого пользователя.
Пользователям, браузер которых поддерживает Javascript, доступно большее количество запросов, в отличие от пользователей, чей браузер не поддерживает Javascript. Попробуйте активировать Javascript в настройках вашего браузера, подождать несколько часов и снова воспользоваться нашим сервером.
Если же ваш компьютер является частью сети компьютеров, в которой большое количество пользователей одновременно пользуется Linguee,сообщитеоб этом нам.
What is lhs/rhs and how is it being used in this program?
lhs and rhs stand for Left Hand Side and Right Hand Side in this context.
They are being used as inputs to operator over loader functions. The Left Hand side is being compared to the Right Hand.
Operator Overloader functions change the way operator symbols work.
Point2D operator+(Point2D lhs, Point2D rhs);
The above code will add (hence the +) the lhs to the rhs. Since Point2D is not a primitive numerical data type, C++ doesn’t know to add two of them together. You are required to tell the compiler how the + operator should be executed for the Point2D datatype.
Каждое значение типа в Swift должно быть Equatable
Я услышал на выступлении Building Better Apps with Value Types in Swift на WWDC15 предложение, о котором никогда не задумывался:
Every Value Type should be Equatable.
Это значит, что каждое значение типа должно соответствовать протоколу Equatable. Это очень «громкое заявление». Ух ты! Каждый тип значения должен быть Equatable ? Хм… давайте разберем все «почему» и «как».
Почему?
Я никогда не задумывался, почему я мог бы хотеть, чтобы все мои типы значений в Swift были Equatable. Не то, чтобы это было ужасной идеей реализовывать оператор == для типа… Я просто никогда не задумывался, что это как раз ожидаемое поведение для типов значений!
Мы интуитивно понимаем, что раз есть значения, то мы можем их сравнивать. Потому что им, значениям, присуще сравнение друг с другом если они одного типа.
Естественно, вызывая две переменные/константы, каждая из которых имеет значение типа Int (потому что в Swift, Int это тип значения), мы ожидаем, что мы можем их сравнить. И, естественно, ожидаем сравнения с реальными числами… с самими значениями.
let a = 10 let b = 5 + 2 + 3 a == b // true let x = 1 let y = 2 x == y // false
Кроме того, мы сравниваем строки на равенство
let str1 = "I love Swift!" let str2 = "I love Swift!" str1 == str2 // true let str3 = "i love swift!" str1 == str3 // false - Так как регистрозависимое сравнение
Фактически, мы ожидаем задавать такого рода вопросы по равенству о любом из типов значений в стандартной библиотеке Swift, не так ли?
Мы действительно проверяем на равенство любой тип значения. В этом и есть смысл.
По этому возникает вопрос, «Как?»
Ответ прост, наши типы значений должны реализовывать оператор ==. И в этом есть кое-что важное:
Свойства равенства
Чтобы быть по-настоящему равным, оператор == должен быть не просто реализован, но и реализован таким образом, чтобы его поведение было именно таким, каким мы его ожидаем, когда сравниваем два объекта. Существует три важных свойства равенства, относящихся к нашим типам значений:
- Сравнение должно быть рефлексивным
- Сравнение должно быть симметричным
- Сравнение должно быть транзитивным
Это звучит ужасно “математически”. На самом деле, эти термины действительно используются в математике. Но не волнуйтесь, эта терминология проста и понятна.
Рефлексивность
Чтобы быть рефлексивным, оператор типа == должен быть уверен, что выражение x == x вернет true.
Поэтому, если у меня let x = 1, и я напишу x == x, я на самом деле получу true, потому что оператор == типа Int является рефлексивным (как и полагается).
Симметрия
Чтобы быть симметричным, оператор == типа должен вычислять значения выражений таким образом, чтобы значение выражений x == y и y == x были одним и тем же (в частности true или false).
Вот пример симметрии:
let x = 1 let y = 1 x == y // true y == x // true let str1 = "Hi" let str2 = "Hello" x == y // false y == x // false
Транзитивность
Наконец, чтобы быть транзитивным, оператор типа == должен быть вычислен таким образом, чтобы при x == y равным true и y == z равным true, получалось что x == z так же должен быть true .
Вот пример транзитивности:
let x = 100 let y = 50 + 50 let z = 50 * 2 x == y // true y == z // true x == z // true
Реализация
Большую часть времени, реализация оператора == происходит очень просто. Если ваш тип значения состоит из других типов значений, которые имеют реализацию оператора == с соответствующей семантикой, то реализация оператора == для вашего типа будет аналогичной.
Пример поможет уложить все в голове. Предположим, что мы пишем приложение по достопримечательностям для местной туристической компании. У нас есть структура, называемая Place, чтобы помочь нам инкапсулировать нашу идею. Это будет выглядеть примерно так:
struct Place < let name: String let latitude: Double let longitude: Double init(name: String, latitude: Double, longitude: Double) < self.name = name self.latitude = latitude self.longitude = longitude >>
Так как Place это тип значения (Struct), которая содержит другие типы значений, вам нужно сделать следующее, чтобы сделать его Equatable:
extension Place: Equatable <> func ==(lhs: Place, rhs: Place) -> Bool
Первое, на что нужно обратить внимание, это то, что оператор == должен быть реализован как автономная глобальная функция, а не как часть определения типа.
Отметим также, что, несмотря на наличие исходника типа, который мы хотим сделать Equatable, я использую протокол Equatable через расширение типа, а не реализовываю его через сам тип. Оба варианта являются приемлемыми, но, обычно выбирают стратегию расширения для данного протокола.
Реализация оператора == использует интуитивную семантику, так как один Place не то же самое, что и другой Place. Но это до тех пор, пока их названия и местоположения не будут одним и тем же.
lhs и rhs просто означают «с левой стороны» или «с правой стороны», соответственно. Поскольку, экземпляр Place находится в левой стороне оператора ==, и экземпляр Place так же находится в правой стороне оператора ==, то когда мы используем это на практике, имеет смысл маркировать эти параметры в соответствии с этим шаблоном.
Реализация может литературно быть прочитана как «если name объекта Place, который находится на левой стороне равно name объекта Place с правой стороны, А ТАК ЖЕ latitude … И … longitude, только тогда эти два Place будут равны между собой.»
Работа с ссылочными типами
Если ссылочные типы связаны с реализацией ваших типов значений, то все может быть намного сложнее. “Сложнее”, вероятно, неправильное слово … но вам придется подумать немного больше о семантике равенства вашего типа.
Давайте немного изменим пример:
Если предположить, что у Place было дополнительное свойство featureImage, которое ссылалось на экземпляр класса UIImage (ссылочный тип), то мы должны проверить наше равенство немного по-другому. И то, как мы проверим равенство зависит от особенностей семантики равенства нашего типа:
- Будут ли два экземпляра Place равны, если они оба указывают на тот же featureImage (т.е. должны ли мы просто использовать === для того чтобы проверить и посмотреть одинаковые ли ссылки используются)?
- Или равны ли два Place, если оба их экземпляра свойства featureImage содержат одни и те же основные растровые изображения (то есть, являются одной и той же картинкой)?
В ответ мы скажем: “смотря как”. Конечно, мы должны проверить на какой-либо тип равенства featureImage, для того, чтобы иметь полную реализацию оператора ==. Но в дальнейшем все действительно сводится к семантике, и нам важно будет знать: « Соответствует ли Place этому Place?»
Для этого примера, я собираюсь рассмотреть последнее заявление: что два Place равны, если оба их featureImage содержат одни и те же основные растровые изображения.
extension Place: Equatable <> func ==(lhs: Place, rhs: Place) -> Bool < let areEqual = lhs.name == rhs.name && lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude && lhs.featureImage.isEqual(rhs.featureImage) // depends on your Type's equality semantics return areEqual >
Итог
Каждый тип значения должен соответствовать протоколу Equatable . В этой статье, мы рассмотрели все “почему” и “как” этих фундаментальных характеристик типов значений. Итак, теперь вы все «в теме», и предвкушаем использование своих знаний в наших кодах!