Заполните список в Kotlin с помощью цикла for

#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;

bool checkValue = false;

int main()
{
    std::thread writer([&](){
            sleep(2);
            checkValue = true;
            std::cout << "Value of checkValue set to " << checkValue << std::endl;
        });

    std::thread reader([&](){
            while(!checkValue);
        });

    writer.join();
    reader.join();
}

Как только интервьюер, который также считал, что volatile бесполезен, со мной спорил, что оптимизация не вызовет никаких проблем и относится к разным ядрам, имеющим отдельные строки кеша и все это (на самом деле не понимало, что именно он ссылаясь на). Но этот фрагмент кода, скомпилированный с -O3 в g ++ (g ++ -O3 thread.cpp -lpthread), показывает неопределенное поведение. В основном, если значение устанавливается перед проверкой while, оно работает нормально, а если нет, оно переходит в цикл, не утруждая себя извлечением значения (которое фактически было изменено другим потоком). В принципе, я считаю, что значение checkValue получает только один раз в регистр и никогда не проверяется снова при самом высоком уровне оптимизации. Если его набор равен true перед выборкой, он работает нормально, и если он не переходит в цикл. Пожалуйста, исправьте меня, если я ошибаюсь.

0
задан Zoe 18 January 2019 в 10:56
поделиться

4 ответа

Ошибка в вашем коде заключается в том, что вы создаете список на каждой итерации цикла. Сначала вы должны составить список, а затем добавить в него каждый элемент цикла!

fun convertRoomClass(course: List<Course>) : List<Courses> {
    val newList = mutableListOf<Courses>()
    course.forEach {
        val id = it.pathID
        val name = it.pathName
        val desc = it.pathDescription
        newList += Courses(id, name!!, desc!!)
    }
    return newList
}

Лучшее решение - использовать функцию карты

fun convertRoomClass(course: List<Course>) = course.map {
   Courses(it.pathID, it.pathDescription!!, it.pathDescription!!)
}
0
ответ дан Ahmed Hegazy 18 January 2019 в 10:56
поделиться

Вы получаете список только с объектом, потому что функция listOf(crs) возвращает список всех объектов, которые передаются в качестве параметров. Сказав то же самое в Java, вы делаете что-то вроде этого:

for (course: Courses) {
    Course course = new Course(...);
    List<Course> list = new ArrayList<>();
    list.add(course);
    return list;
}

Как вы можете видеть, он создал новый список с одним объектом на итерацию. То, что вы пытаетесь достичь, может быть сделано с помощью оператора map{...}, который просто преобразует каждый объект в исходном списке, используя код, переданный внутрь map, и возвращает список преобразованных объектов

course.map{ Courses(...) }

Также я Вы заметили, что вы используете оператор !! при создании объекта Courses. Возможно, потому что Course может иметь имя nullable, а Courses - нет. Я считаю это плохой практикой, потому что в этом случае вы говорите

Пожалуйста, бросьте Exception, если имя null.

Я думаю, что гораздо лучший подход заключается в предоставлении альтернативы, например:

val name = course.name ?: "default", говоря

Пожалуйста, используйте name или [1115 ] если name равно null.

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

0
ответ дан Demigod 18 January 2019 в 10:56
поделиться

Возможно, вы ищете Котлин Карта

Пример:

course.map { Courses(it.pathID, it.pathName,it.pathDescription) }
0
ответ дан Milind Mevada 18 January 2019 в 10:56
поделиться

Вы можете использовать MutableList вместо List. Это позволяет вам добавлять новый элемент в конец вашего списка, а не заменять весь список, выполнив: list = listOf(crs)

Так что замените тип вашего var lateinit var list : List<Courses> на lateinit var list : MutableList<Courses>, а затем замените list = listOf(crs) list.add(crs)

Надеюсь, что это помогает и весело провести время :)

0
ответ дан Guillaume Monrolin 18 January 2019 в 10:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: