# Coroutine Context

* `CoroutineContext` serves as a vital interface and a cornerstone of coroutines.
    
* A coroutine launches with a context and remains tied to it until the completion or cancellation of its job.
    
* It represents an indexed set of `Element` instances.
    
    * An **indexed set** combines the characteristics of a set and a map.
        
    * Each element in this set possesses a **unique key**.
        
    * `Element` implements the `CoroutineContext` interface.
        
        * An element within the coroutine context is a singleton context on its own.
            
* By default, any coroutine builder or scope function utilizes an empty coroutine context known as `EmptyCoroutineContext`.
    
* It is generally discouraged to access the `coroutineContext` property of a `CoroutineScope` in regular code
    
    * except when accessing the `Job` instance for advanced purposes.
        

#### **Code blocks**

* `CoroutineContext` interface holds these given below three blocks of code.
    

```kotlin
public interface CoroutineContext {
    public operator fun <E : Element> get(key: Key<E>): E?
    public operator fun plus(context: CoroutineContext): CoroutineContext {}
    public fun minusKey(key: Key<*>): CoroutineContext
    public fun <R> fold(initial: R, operation: (R, Element) -> R): R
}
```

```kotlin
public interface Key<E : Element>
```

```kotlin
public interface Element : CoroutineContext {
    // A key of this coroutine context element.
    public val key: Key<*>

    public override operator fun <E : Element> get(key: Key<E>): E? {}
    public override fun minusKey(key: Key<*>): CoroutineContext = {}
    public override fun <R> fold(initial: R, operation: (R, Element) -> R): R {}
}
```

* A few examples of `CoroutineContext`'s `Element` are:
    
    * EmptyCoroutineContext, CombinedContext
        
    * AbstractCoroutineContextElement
        
    * EventLoop, BlockingEventLoop
        
    * Dispatcher, DefaultScheduler
        

### **Example**

```kotlin
@OptIn(ExperimentalStdlibApi::class)
suspend fun main() {

    val coroutineName = CoroutineName("Name: EmptyCoroutineContext") + EmptyCoroutineContext
    val job = GlobalScope.launch(coroutineName) {
        val dispatcher = coroutineContext[CoroutineDispatcher]
        val name = coroutineContext[CoroutineName]?.name
        println("Coroutine Context details: $name , Dispatcher: $dispatcher")
    }
    job.join()
}
```

Happy coding... 😊
