#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 перед выборкой, он работает нормально, и если он не переходит в цикл. Пожалуйста, исправьте меня, если я ошибаюсь.
Ошибка в вашем коде заключается в том, что вы создаете список на каждой итерации цикла. Сначала вы должны составить список, а затем добавить в него каждый элемент цикла!
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!!)
}
Вы получаете список только с объектом, потому что функция 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
- нет. Я считаю это плохой практикой, потому что в этом случае вы говорите
Пожалуйста, бросьте
blockquote>Exception
, если имяnull
.Я думаю, что гораздо лучший подход заключается в предоставлении альтернативы, например:
val name = course.name ?: "default"
, говоряПожалуйста, используйте
blockquote>name
или [1115 ] еслиname
равноnull
.или пропустите объекты без имени, или любой другой подход, подходящий для вашей ситуации.
Возможно, вы ищете Котлин Карта
Пример:
course.map { Courses(it.pathID, it.pathName,it.pathDescription) }
Вы можете использовать MutableList вместо List. Это позволяет вам добавлять новый элемент в конец вашего списка, а не заменять весь список, выполнив: list = listOf(crs)
Так что замените тип вашего var lateinit var list : List<Courses>
на lateinit var list : MutableList<Courses>
, а затем замените list = listOf(crs)
list.add(crs)
Надеюсь, что это помогает и весело провести время :)