Хобрук: Ваш путь к мастерству в программировании

Все ли в Котлине является объектом?

Я читал это в нескольких местах. Но толком не понял смысла. Вы можете прочитать эту краткую документацию по kotlinlang:

«В Kotlin все является объектом в том смысле, что мы можем вызывать функции-члены и свойства для любой переменной. Некоторые типы могут иметь специальное внутреннее представление — например, числа, символы и логические значения могут быть представлены как примитивные значения во время выполнения — но для пользователя они выглядят как обычные классы».

Что такое особое внутреннее представление? Что это значит, могут быть представлены в виде примитивных значений во время выполнения?

Это только возможность вызова функций преобразования, таких как toInt()? А функции расширения?

В другом месте я прочитал следующее утверждение:

«Для примитивных типов данных из java в kotlin есть специализированные типы массивов, такие как ByteArray». Означает ли это, что я могу создать массив в Kotlin только с такими функциями, как intArrayOf(1, 2, 3) или IntArray(5)?

Еще одно утверждение, которое я нахожу сбивающим с толку, из книги Head First Kotlin:

«Когда вы объявляете переменную, используя такой код:

var x = 5 

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

«Когда объект присваивается переменной, сам объект не входит в переменную. Вместо этого в переменную помещается ссылка на объект:

введите описание изображения здесь

Но следующий фрагмент кода делает то же самое, что и Java.

fun main() {
    var x = 5
    var y = x
    x = 15
    println("Hello, world!!! $y")
}

Вывод 5. Но я думаю, что должно быть 15, потому что это объект и ссылка на него. Может быть, я немного глуп, чтобы понять Котлин. Это мое понимание переменных, ссылок и управления памятью в таких языках программирования, как Java (или Kotlin).

введите описание изображения здесь

31.07.2019

  • Я думаю, вам повезет больше, если вы сможете разбить свой вопрос на несколько более мелких вопросов, каждый из которых фокусируется на одной области путаницы. 31.07.2019

Ответы:


1

давайте подумаем, что это объекты, а не примитивы

var x = 10

назначить ссылку 10 на x

var y = x

назначить ссылку x на y

x = 5

назначьте ссылку 5 на x, чтобы ссылка x изменилась, но y сохранила ссылку 10

по-другому

если вы можете сделать что-то вроде этого

x.changeSomeOfMyProperties()

затем изменения будут применены к x и y, но, поскольку они являются примитивами, вы не можете делать такие вещи. примитивы — это классы в kotlin, поэтому сложно понять, как они работают, вы можете проверить Primitives.kt

31.07.2019

2

На выходе 5. Но думаю должно быть 15

Мы можем пройтись по тому, что происходит в этом образце.

var x = 5

Создайте объект Int, содержащий значение 5. Создайте переменную x и сделайте так, чтобы x указывало на этот новый объект Int.

var y = x

Создайте переменную y и сделайте так, чтобы y указывало на то, на что в данный момент указывает x (объект Int).

(Обратите внимание, что это не случай, когда x и y являются двумя именами для одного и того же указателя. Скорее, x и y полностью различны, но оба указывают на одно и то же.)

x = 15

Создайте объект Int, содержащий значение 5. Сделайте так, чтобы переменная x указывала на этот новый объект Int.

(Это ключевой момент в потоке. Когда мы назначаем x = 15, мы меняем точку, на которую указывает x, но мы совсем не затрагиваем y. y по-прежнему указывает на то же, что и раньше (Int, удерживающее 5)).

println("Hello, world!!! $y")

Показать что-то пользователю. Чтобы определить, чем заменить $y, следуйте за указателем и посмотрите, на что он указывает. y было присвоено значение только один раз, поэтому он по-прежнему указывает на первое, на что он когда-либо указывал (Int содержит 5).

31.07.2019

3

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

для последнего:

x = 5 //and let's say int 5 memory location is A235

so

y = x is synonymous to y = A235

тогда

x = 15

но y все еще указывает на значение ячейки памяти A235

31.07.2019

4

Все примитивы представлены как соответствующие им типы JVM, если только вы специально не обращаетесь к ним как или не заставляете их быть объектами.

Чтобы показать, что я имею в виду, давайте воспользуемся функцией System.identityHashCode(Object). Также используйте значение Int > 127 для предотвращения кэширования объектов.

Случай 1: примитивы

fun main(){
    var x = 128
    var y = x
    println("x: $x, ${System.identityHashCode(x)}")
    println("x: $x, ${System.identityHashCode(x)}")
    println("y: $y, ${System.identityHashCode(y)}")

    x = 200
    println("x: $x, ${System.identityHashCode(x)}")
}

/// output
x: 128, 746292446
x: 128, 1072591677
y: 128, 1523554304
x: 200, 1175962212

Что мы получаем здесь: x является примитивом int и хранится как таковой. когда y = x, это означает, что y присваивается то же примитивное значение, что и x. Objects еще не выделено.

Когда мы используем System.identityHashCode(Object), мы получаем разные хэши, даже если мы печатаем x дважды подряд. Это потому, что Int объекты-оболочки создаются там, где требуется Object представление.

Случай 2: представление объекта

fun main() {
    var x : Any = 128  // this is the only line that changed
    var y = x
    println("x: $x, ${System.identityHashCode(x)}")
    println("x: $x, ${System.identityHashCode(x)}")
    println("y: $y, ${System.identityHashCode(y)}")

    x = 200
    println("x: $x, ${System.identityHashCode(x)}")
}

/// output
x: 128, 746292446
x: 128, 746292446
y: 128, 746292446
x: 200, 1072591677

Здесь мы заставляем x быть представленным как Object, объявляя тип поля непримитивным. Когда мы назначаем x y, эта ссылка на объект копируется, и мы можем видеть, что identityHashCode возвращает один и тот же хеш во всех отпечатках.

31.07.2019
  • Спасибо, но что это значит, еще один HashCode? Есть ли в этом преимущество? 01.08.2019
  • Хэш-код идентификации @TorbenG возвращает хэш на основе адреса памяти. Если хеш-код тот же, это означает, что мы ссылались на один и тот же объект. Если это не так, значит, у нас разные объекты. 01.08.2019

  • 5

    Но в чем здесь отличие от Java? Я думаю, что Java делает то же самое с примитивными переменными, такими как x и y. Когда мы назначаем y на x в Java и после этого меняем x, y все еще имеет старое значение. Потому что это копия, а не ссылка.

    Итак, единственная разница между Kotlin и Java заключается в том, что я могу вызывать функции для примитивных типов данных и присваивать им свойства, как с объектами?

    02.08.2019
    Новые материалы

    Что такое структура данных?
    Структура данных хранит и извлекает данные. Все, что обеспечивает эти две функции, является структурой данных . Период. Вы можете пропустить оставшуюся часть статьи, если ответ..

    мои январские чтения по программированию
    Эрик Эллиот Программирование приложения JavaScript Эл Свейгарт «Автоматизируйте скучные вещи с помощью Python» Прогрессивное веб-приложение Google..

    Создание ассоциаций секвелизации с помощью инструмента командной строки Sequelize
    Sequelize - популярный, простой в использовании инструмент объектно-реляционного сопоставления (ORM) JavaScript, который работает с базами данных SQL. Довольно просто начать новый проект с..

    Искусственный интеллект в юридической отрасли - пример прогнозирования судебных решений с помощью глубокого обучения
    На протяжении всей истории люди полагались на суды, присяжных, королей и королев в отправлении правосудия. Сегодня способность судов обеспечивать справедливое и быстрое правосудие для своих..

    Введение в машинное обучение для обнаружения аномалий (часть 1)
    Тщательно созданный, тщательно спроектированный ресурс для специалистов по данным. Часть 1 Главы 03 из Руководства по машинному обучению для обнаружения аномалий Внимание! Прежде чем вы..

    Начало работы с Pulumi в Digital Ocean
    Цифровой океан (ДО) — отличная альтернатива многим другим поставщикам облачных услуг. DO предоставляет простой и понятный пользовательский интерфейс, упрощающий управление инфраструктурой и..

    #Day68 из #100days_of_coding
    Вчера был мой 68-й день кодинга. я решил один вопрос Проблема: Разбить двоичную строку на подстроки с равным количеством нулей и единиц Дана двоичная строка str длины N . Задача состоит..